I have added a DependencyProperty to my View, binding to the DependencyProperty works, but only if I do not also set the DataContext.
GenericView.xaml
<UserControl x:Class="GenericProject.View.GenericView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<Button Command="{Binding VMFactory.CreateViewModelCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<TextBox IsEnabled="False" Text="{Binding SomeProperty, Mode=OneWay}" />
</StackPanel>
</UserControl>
GenericView.xaml.cs
public partial class GenericView : UserControl
{
// The DependencyProperty for VMFactory.
public static readonly DependencyProperty VMFactoryProperty = DependencyProperty.Register("VMFactory", typeof(VMFactoryViewModel<GenericViewModel>), typeof(GenericView));
public VMFactoryViewModel<GenericViewModel> VMFactory
{
get { return (VMFactoryViewModel<GenericViewModel>)GetValue(VMFactoryProperty); }
set { SetValue(VMFactoryProperty, value); }
}
public GenericView()
{
InitializeComponent();
}
}
Here I am creating two views to illustrate the issue at hand. The VMFactory binding in the first view will fail because I have DataContext set. The second view will succeed, what is the cause of this behavior?
MainPage.xaml
<vw:GenericView DataContext="{Binding Generic}" VMFactory="{Binding GenericFactory}" />
<vw:GenericView VMFactory="{Binding GenericFactory}" />
I've got a working solution, it seems as though properties of a control are bound relative to the DataContext of the control?
I was certainly aware items within the control would be bound relative to the DataContext, but I apparently have never used a control in this way before and did not understand that properties of the control would also inherit the scope of the set DataContext. Essentially everything within my View was correct, but the binding to my DependencyProperty was failing.
GenericView.xaml
MainPage.xaml
As @toadflakz said, this is a very common issue in WPF and one that took me a while to get my head around when I was learning WPF. Luckily, the solution is simple. Let's say that we have a
UserControl
that has an object set as itsDataContext
and another set as the value of aDependencyProperty
that is declared within theUserControl
... your situation.From within the
UserControl
XAML, you can data bind to a property of the object set as theDataContext
as normal:If you want to data bind to an object from the object set as the value of the
DependencyProperty
, you can simply use aRelativeSource Binding
:Note that both of these
Binding
s can be used together in the sameUserControl
as long as both of theDataContext
andDependencyProperty
properties have been set.This is a fairly common Binding "gotcha"...
In order to access
VMFactory
, you need to bind yourUserControl
to itself using...You would not then bind
DataContext
on aGenericView
item to anything elsewhere.However, if you are intending to bind other values to
VMFactory
external to theUserControl
(i.e.<vw:GenericView VMFactory={Binding ...}"/>
), you should useRelativeSource
with modeFindAncestor
for typeUserControl
.