如果您有一组预定义的上下文菜单,想要根据特定场景使用,您始终可以将上下文菜单创建为资源。
<Window.Resources>
<ContextMenu x:Key="Menu1">
<MenuItem>Item1</MenuItem>
</ContextMenu>
<ContextMenu x:Key="Menu2">
<MenuItem>Item1</MenuItem>
<MenuItem>Item2</MenuItem>
</ContextMenu>
</Window.Resources>
然后在您的ListBox 上创建数据触发器以设置要使用的ContextMenu,而不是我在下面所做的,我建议绑定到您的视图模型上的属性或为此的代码,因为它可能会变得非常混乱在xml中。
这里的实现检查是否只选择了一个项目,在这种情况下切换到 Menu1
<ListBox x:Name="mylist" SelectionMode="Multiple" ContextMenu="{StaticResource Menu2}" >
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=SelectedItems.Count, RelativeSource={RelativeSource Self}}" Value="1" >
<Setter Property="ContextMenu" Value="{StaticResource ResourceKey=Menu1}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.Style>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=DisplayName}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
如果选择显示哪个上下文菜单只与视图有关,我建议在后面的代码中处理它。
public partial class MainWindow : Window
{
public MainWindow()
{
// Hook up any events that might influence which menu to show
mylist.SelectionChanged += listSelectionChanged;
InitializeComponent();
}
private void listSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = sender as ListBox;
if (listBox == null)
return; // Or throw something, hard
ContextMenu menuToUse;
// Logic for selecting which menu to use goes here
listBox.ContextMenu = menuToUse;
}
}
虽然如果 ViewModel 确实对显示哪个菜单感兴趣(听起来不像,但如果不知道完整的上下文很难分辨),您可以公开一些属性,让您在 ViewModel 中决定 ContextMenu以显示。尽管您很可能希望创建一个类来确保在任何给定时间只有一个布尔值为真,而不是单个布尔属性。
public class MyViewModel : INotifyPropertyChanged
{
public MyViewModel()
{
SelectedItems = new ObservableCollection<string>();
SelectedItems.CollectionChanged += SelectedItemsChanged;
}
private void SelectedItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// Logic to see which ShowMenuX property to set to true goes here
}
public ObservableCollection<string> SelectedItems { get; set; }
private bool _showMenu1 = false;
public bool ShowMenu1
{
get { return _showMenu1; }
set
{
_showMenu1 = value;
RaisePropertyChanged("ShowMenu1");
}
}
// INotifyPropertyChanged implementation goes here
}