ContextMenu不管定義在.cs或.xaml文件中,都不繼承父級的DataContext,因此若是要綁定父級的DataContext,直接DataContext=「{Binding}」是行不通的ide
不能綁父級,可是能綁資源spa
第一步:定義一箇中間類用來作資源對象code
1 public class BindingProxy : Freezable 2 { 3 #region Overrides of Freezable 4 5 protected override Freezable CreateInstanceCore() 6 { 7 return new BindingProxy(); 8 } 9 10 #endregion 11 12 public object Data 13 { 14 get { return (object)GetValue(DataProperty); } 15 set { SetValue(DataProperty, value); } 16 } 17 18 public static readonly DependencyProperty DataProperty = 19 DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); 20 }
第二步:引用命名空間,在控件中定義資源對象
1 <UserControl.Resources> 2 <libBinding:BindingProxy x:Key="BindingProxy" Data="{Binding}"/> 3 </UserControl.Resources>
第三步:綁定ContextMenu、MenuItemblog
(Button.Command 和 ContextMenu.IsOpen 的綁定部分能夠不關注,這兩個綁定是用來控制ContextMenu打開的)繼承
1 <Button Command="{Binding Customfold}"> 2 <Button.ContextMenu> 3 <ContextMenu DataContext="{Binding Data,Source={StaticResource BindingProxy}}" 4 ItemsSource="{Binding ItemModelCollection}" 5 IsOpen="{Binding OpenCustomfold,Mode=OneWay}"> 6 <ContextMenu.ItemContainerStyle> 7 <Style TargetType="MenuItem"> 8 <Setter Property="Header" Value="{Binding ...}"/> 9 <Setter Property="Command" Value="{Binding ...}"/> 10 <Setter Property="CommandParameter" Value="{Binding ...}"/> 11 </Style> 12 </ContextMenu.ItemContainerStyle> 13 </ContextMenu> 14 </Button.ContextMenu> 15 <Image .../> 16 </Button>
第四步:傳遞參數資源
ContextMenu是它自身視覺樹的根節點,因此即便經過RelativeSource.FindAncestor也找不到要傳遞的參數。get
解決:能夠經過PlacementTarget解決。微軟對PlacementTarget的解釋是:獲取或設置UIElement,當它打開時相對於它肯定ContextMenu的位置。應該能夠理解爲放置此ContextMenu的UIElement。it
1 CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget}" io
若是要傳遞Item,如ListBox的SelectedItem:
1 CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}"
參考: