Why
- 在使用
WPF中,如果你使用ContextMenu时会发现,当你直接绑定到ViewModel的时候并不会起作用,其实主要的原因是ContextMenu是一个弹出层,类似的还有一个是ToolTip,类似的用法,它本身的虚拟树就是它自己,以下是最方便的绑定方法。
How
public class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object DataContext
{
get { return (object)GetValue(DataContextProperty); }
set { SetValue(DataContextProperty, value); }
}
// Using a DependencyProperty as the backing store for DataContext. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataContextProperty =
DependencyProperty.Register("DataContext", typeof(object), typeof(BindingProxy), new PropertyMetadata(null));
}
<UserControl.Resources>
<ResourceDictionary>
<comm:BindingProxy x:Key="BindingProxy" DataContext="{Binding}" />
<ContextMenu x:Key="menu1" DataContext="{Binding Source={StaticResource BindingProxy}, Path=DataContext}">
<ContextMenu.Items>
<MenuItem
Command="{Binding MenuTestCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}"
Header="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}" />
<MenuItem
Command="{Binding MenuTestCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget}"
Header="Item2" />
</ContextMenu.Items>
</ContextMenu>
</ResourceDictionary>
</UserControl.Resources>
<ListView
Height="100"
comm:TextBoxHelper.AutoScrollToEnd="True"
ContextMenu="{StaticResource menu1}"
ItemsSource="{Binding Names}" />
- 其中需要先赋值当前数据上下文给到代理,然后设置给
ContextMenu。
- 其余在绑定基本一致,但是有个不一样的地方就是
PlacementTarget,简单理解都是获取这个ContextMenu被放置在哪个控件上,获取方法就是使用这个,例如获取ListView被选中的目标就是使用SelectedItem,注意这个时候是没有语法提示的。
Tips
- 最简单的绑定方法,同时也通用,类似的还有
ToolTip弹出层。
- 注意获取当前被放置的控件时使用
PlacementTarget。