赞
踩
需求:
在ListBox中的Item上点击右键时弹出菜单,由于使用MVVM架构,需要把为MenuItem绑定Command,并能把选择的ListBoxItem传递到ViewModel。
实现:
1、只对被点击的ListItem弹出ContextMenu,只需要建立一个DataTemplate即可,这个比较简单。
2、绑定Command,这个是比较麻烦的,查了许多资料,就是利用PlacementTarget来确定ContextMenu的位置,这个方法是正确,但是使用MVVM架构时,由于ContextMenu没有父级节点,不能继承DataContext,所以通过直接设置Command不能找到View所绑定DataContext,从而导致绑定失败。
解决办法是将ViewModel绑定的需要弹出ContextMenu的控件的Tag上,在ContextMenu通过绑定PlacementTarget的Tag来获取ViewModel,然后在设置Command就可以生效了。
3、通过CommandParameter传递选择的ListBoxItem,最开始我用的是PlacementTarget.SelectedItem,但是传到后边的一直是null,调试了好久,突然想明白由于设置的ContextMenu是在附加在DataTemplate中的一个控件上,并不是附加在ListBox上,所以PlacementTarget根本就没有SelectedItem这个属性。而应该使用PlacementTarget.DataContext来获取ContextMenu附着的ListBoxItem。
经过测试可以完美绑定Command并传递选择的Item到后台ViewModel,问题解决!
前台View的DataTemplate代码如下,后台ViewModel比较简单就不贴了,使用的是MVVMLight:
<DataTemplate x:Key="DataTem">
<StackPanel x:Name="panel" Tag="{Binding Source={StaticResource Locator}, Path=TestVM, Mode=OneWay}">
<StackPanel.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="菜单项1" Command="{Binding Command1}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.DataContext}"/>
<MenuItem Header="菜单项2" Command="{Binding Command2}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.DataContext}"/>
</ContextMenu>
</StackPanel.ContextMenu>
<TextBlock Margin="8" FontSize="16" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
参考了这个帖子:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。