WPF ContextMenu 在MVVM模式中綁定 Command及使用CommandParameter傳參

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}"  

參考:

http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

http://stackoverflow.com/questions/1580753/wpf-contextmenu-with-itemssource-how-to-bind-to-command-in-each-item

相關文章
相關標籤/搜索