У меня есть представление, которое объявлено в XAML (см. Ниже).Соответствующая модель представления создается автоматически с использованием MEF.Я хочу иметь возможность сделать что-то вроде этого:
<local:MyControl Owner={x:Static local:Owners.ProjectOwner} />
Желаемый чистый эффект для некоторого свойства view-model, установленного равным Owners.ProjectOwner.
Я могу достичьТребуемый результат с использованием хакерского кода, но он будет делать это через привязки или каким-либо другим способом.Может кто-нибудь предложить способ сделать это?
ОБНОВЛЕНИЕ
Я смирился с написанием поведения.Но вместо того, чтобы приложить все усилия исключительно для одного конкретного случая, я обобщил свое решение и включаю его ниже на случай, если кому-то будет интересно.Это смешанное поведение (System.Windows.Interactivity.dll), но оно также может быть обычным присоединенным поведением.
using System;
using System.Windows;
using System.Windows.Interactivity;
namespace BlendBehaviors
{
public class SetViewModelPropertyBehavior : Behavior<FrameworkElement>
{
public static readonly DependencyProperty PropertyNameProperty =
DependencyProperty.Register("PropertyName", typeof(string), typeof(SetViewModelPropertyBehavior));
public static readonly DependencyProperty PropertyValueProperty =
DependencyProperty.Register("PropertyValue", typeof(object), typeof(SetViewModelPropertyBehavior));
public SetViewModelPropertyBehavior()
{ }
public string PropertyName
{
get { return (string)GetValue(PropertyNameProperty); }
set { SetValue(PropertyNameProperty, value); }
}
public object PropertyValue
{
get { return GetValue(PropertyValueProperty); }
set { SetValue(PropertyValueProperty, value); }
}
protected override void OnAttached()
{
base.OnAttached();
var ao = AssociatedObject;
SetViewModel(ao.DataContext);
ao.DataContextChanged += FrameworkElement_DataContextChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.DataContextChanged -= FrameworkElement_DataContextChanged;
}
private void FrameworkElement_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
SetViewModel(e.NewValue);
}
private void SetViewModel(object viewModel)
{
SetViewModelProperty(viewModel, PropertyName, PropertyValue);
}
private static void SetViewModelProperty(object viewModel, string propertyName, object propertyValue)
{
if (viewModel == null || propertyName == null) {
return;
}
var info = viewModel.GetType().GetProperty(propertyName);
if (info != null && CanAssignValue(propertyValue, info.PropertyType)) {
info.SetValue(viewModel, propertyValue, null);
}
}
private static bool CanAssignValue(object value, Type targetType)
{
if (value == null) {
return !targetType.IsValueType || Nullable.GetUnderlyingType(targetType) != null;
}
return targetType.IsAssignableFrom(value.GetType());
}
}
}
Затем используйте его следующим образом:
<local:MyControl>
<i:Interaction.Behaviors>
<bb:SetViewModelPropertyBehavior PropertyName="Owner" PropertyValue="{x:Static local:Owners.ProjectOwner}" />
<bb:SetViewModelPropertyBehavior PropertyName="AnotherProperty" PropertyValue="{StaticResource MyResourceKey}" />
</i:Interaction.Behaviors>
</local:MyControl>