views:

479

answers:

2

I have a WPF UserControl containing a custom DependencyProperty named MyDP. I want to bind this to a property on my ViewModel (which is injected as the UserControl's DataContext). I know one way to do it by setting the binding in the UserControl's declaration in the parent window's XAML as such:

<Window x:Class="MyNamespace.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:views="clr-namespace:MyNamespace.Views">
    <StackPanel>
        <views:MyControl MyDP="{Binding Path=MyVMProperty, Mode=OneWayToSource}"/>
    </StackPanel>
</Window>

This works fine, but as an alternate could I set up the binding inside the UserControl's XAML, similar to how I set the bindings for the individual controls inside the UserControl to other properties of the ViewModel?

A: 

Yes. That should work just fine from inside the UserControl's XAML since the DataContext of the UserControl is already set to the ViewModel. I believe you would do it at the very top:

<UserControl x:Class="WpfApplication1.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    MyDP="{Binding Path=MyVMProperty, Mode=OneWayToSource}">
Joel B Fant
This won't compile for reasons explained in my answer.
John Bowen
Yep, forgot about that. Got sloppy and wrote it before testing it in a project.
Joel B Fant
+2  A: 

You can't do what you were originally thinking directly. You probably tried and got some compile errors. You can't set a custom property inline in the UserControl's root XAML because the element type is UserControl so the compiler is enforcing property names based on that type, not your custom type. You could get around this by changing to an Attached Property but that actually changes the meaning of MyDP. Instead you can set a default in the Style for the UserControl and get an additional benefit of being able to override it on any declared instance by just doing what's in your original example. Set this under your UserControl's root element:

<UserControl.Style>
    <Style>
        <Setter Property="views:MyControl.MyDp" Value="{Binding Path=MyVMProperty, Mode=OneWayToSource}" />
    </Style>
</UserControl.Style>
John Bowen
That worked perfectly, thanks! Not the most obvious approach to this WPF noob, but your explanation certainly clarifies the situation.
Tim Trout