How to bind a child UserControl's Dependency Property, using Style, to a property of the host element's view-model?
I tried the code below, and MyBlock.BlockIsOnlyOne should be bound to the view-model's property - MyContainerViewModel.ViewModelIsOnlyOne, via the Style's Setter. But from some reason it just doesn't work - the MyBlock.BlockIsOnlyOne's value never changes, although the MyContainerViewModel.ViewModelIsOnlyOne changes...
The Container XAML:
<UserControl x:Class="MyNs.MyContainer"
...
>
<UserControl.DataContext>
<vc:MyContainerViewModel x:Name="TheDataContext"/>
</UserControl.DataContext>
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type vc:MyBlock}">
<Setter Property="BlockIsOnlyOne" Value="{Binding ViewModelIsOnlyOne}"/>
<!-- Tried this too, with no success: -->
<!-- <Setter Property="BlockIsOnlyOne" Value="{Binding ViewModelIsOnlyOne, ElementName=TheDataContext}"/> -->
</Style>
</Grid.Resources>
...
<vc:MyBlock DataContext="{Binding PortA[0]}" />
</Grid>
</UserControl>
The Container's ViewModel (only the important part...):
[NotifyPropertyChangedAspect] // handles the INotifyPropertyChanged implementation...
class MyContainerViewModel{
...
public bool ViewModelIsOnlyOne { get; private set; }
...
}
The MyBlock UserControl:
class MyBlock : UserControl{
...
public static readonly DependencyProperty BlockIsOnlyOneProperty = DependencyProperty.Register(
"BlockIsOnlyOne", typeof (bool), typeof (MyBlock),
new PropertyMetadata(default(bool), BlockIsOnlyOne_PropertyChangedCallback));
private static void BlockIsOnlyOne_PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs a)
{
var @this = dependencyObject as MyBlock;
if (@this == null) return;
Trace.WriteLine(string.Format("Old: {0}, New: {1}", a.OldValue, a.NewValue)); // never seems to fire...
}
public bool BlockIsOnlyOne
{
get { return (bool) GetValue(BlockIsOnlyOneProperty); }
set { SetValue(BlockIsOnlyOneProperty, value); }
}
...
}
You should be able to reach your view model property from the
UserControlusing aRelativeSource Binding. The idea is to search for the parent view that the view model is set as theDataContextusing theAncestorTypeproperty... try this:If that picks up the child
UserControl.DataContextinstead, then you could either set theRelativeSource.AncestorLevelProperty to the appropriate level, or use the name/type of your parentUserControlinstead: