Reputation: 9015
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); }
}
...
}
Upvotes: 0
Views: 1693
Reputation: 69979
You should be able to reach your view model property from the UserControl
using a RelativeSource Binding
. The idea is to search for the parent view that the view model is set as the DataContext
using the AncestorType
property... try this:
<Style TargetType="{x:Type vc:MyBlock}">
<Setter Property="DataContext.BlockIsOnlyOne" Value="{Binding ViewModelIsOnlyOne,
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
</Style>
If that picks up the child UserControl.DataContext
instead, then you could either set the RelativeSource.AncestorLevel
Property to the appropriate level, or use the name/type of your parent UserControl
instead:
<Style TargetType="{x:Type vc:MyBlock}">
<Setter Property="BlockIsOnlyOne" Value="{Binding DataContext.ViewModelIsOnlyOne,
RelativeSource={RelativeSource AncestorType={x:Type YourPrefix:MyContainer}}}" />
</Style>
Upvotes: 2