I have a view that is declared in XAML (see below). A linked view model is created automatically using MEF. I want to be able to do something like this:
<local:MyControl Owner={x:Static local:Owners.ProjectOwner} />
The desired network effect is a property of some property of the view model, equal to Owners.ProjectOwner.
I can achieve the desired result using the hacker code, but rather I will do it with the help of bindings or in some other way. Can anyone suggest a way to do this?
UPDATE
I put up with what I wrote about behavior. But instead of making every effort exclusively to one specific case, I summarized my decision, and I included it below, if someone is interested. This is the behavior of Blend (System.Windows.Interactivity.dll), but it can just as easily be the usual attached behavior.
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()); } } }
Then use it as follows:
<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>