title: Setting a ViewModel Property Value From XAML
body: <p>I have a view that is declared in XAML (see below).  The associated view-model is created automatically using MEF.  I want to be able to do something like this:</p>
  
  <pre><code>&lt;local:MyControl Owner={x:Static local:Owners.ProjectOwner} /&gt;
  </code></pre>
  
  <p>The desired net effect is for some view-model property to be set equal to Owners.ProjectOwner.</p>
  
  <p>I can achieve the required result using hacky code-behind but would rather do this through bindings or some similar manner.  Can anyone suggest a way of doing this?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I resigned myself to writing a behaviour.  But rather than put in all the effort solely for one specific case, I have genericised my solution and I include it below in case anyone's interested.  It's a Blend behaviour (System.Windows.Interactivity.dll) but could just as easily be a conventional attached behaviour.</p>
  
  <pre><code>using System;
  using System.Windows;
  using System.Windows.Interactivity;
  
  namespace BlendBehaviors
  {
      public class SetViewModelPropertyBehavior : Behavior&lt;FrameworkElement&gt;
      {
          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 &amp;&amp; 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());
          }
      }
  }
  </code></pre>
  
  <p>Then use it like this:</p>
  
  <pre><code>&lt;local:MyControl&gt;
      &lt;i:Interaction.Behaviors&gt;
          &lt;bb:SetViewModelPropertyBehavior PropertyName="Owner" PropertyValue="{x:Static local:Owners.ProjectOwner}" /&gt;
          &lt;bb:SetViewModelPropertyBehavior PropertyName="AnotherProperty" PropertyValue="{StaticResource MyResourceKey}" /&gt;
      &lt;/i:Interaction.Behaviors&gt;
  &lt;/local:MyControl&gt;
  </code></pre>