Reputation: 2153
I'm wondering how do I set the bindings to a public variable within my Viewmodel WorkTabViewModel. I set two examples I tried below,
The Foreground="{Binding MenuItemForeground}"
and
Foreground="{Binding MenuItemForeground, RelativeSource={RelativeSource AncestorType=UserControl}}"
But they both don't recognize MenuItemForeground.
<TextBlock VerticalAlignment="Center" FontWeight="Bold" Margin="1 0 0 0" DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType=UserControl}}" >
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Close tab" cal:Message.Attach="[Click] = [CloseTab()]" />
<MenuItem Header="Close other tabs" cal:Message.Attach="[Click] = [CloseOtherTabs()]" IsEnabled="False" Foreground="{Binding MenuItemForeground, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
<MenuItem Header="Close all tabs" cal:Message.Attach="[Click] = [CloseAllTabs()]" IsEnabled="False" Foreground="{Binding MenuItemForeground}"/>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
WorkTabViewModel
public Brush MenuItemForeground { get; set; }
public void CloseTab(){...}
public void CloseOtherTab(){...}
public void CloseAllTabs(){...}
Upvotes: 0
Views: 384
Reputation: 3312
A context menu is not a part of the visual tree so it's not inheriting the parent controls DataContext. You also can't use the ancestor syntax because of this.
One solution is to use a binding proxy.
public class BindingProxy : Freezable
{
#region Overrides of Freezable
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
#endregion
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data",
typeof(object),
typeof(BindingProxy),
new UIPropertyMetadata(null));
}
And it's usage in XAML.
<TextBlock VerticalAlignment="Center"
FontWeight="Bold"
Margin="1 0 0 0"
DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType=UserControl}}">
<TextBlock.Resources>
<helper:BindingProxy x:Key="proxy"
Data="{Binding }" />
</TextBlock.Resources>
<TextBlock.ContextMenu>
<MenuItem Header="Close tab"
cal:Message.Attach="[Click] = [CloseTab()]" />
<MenuItem Header="Close other tabs"
cal:Message.Attach="[Click] = [CloseOtherTabs()]"
IsEnabled="False"
Foreground="{Binding Source={StaticResource proxy}, Data.MenuItemForeground}"/>
<MenuItem Header="Close all tabs"
cal:Message.Attach="[Click] = [CloseAllTabs()]"
IsEnabled="False"
Foreground="{Binding Source={StaticResource proxy}, Data.MenuItemForeground}"/>
</ContextMenu>
</TextBlock.ContextMenu>
Don't forget to declare the helper namespace import at the top of your Window/UserControl.
Upvotes: 1