C# 根据WPF中的情况自定义菜单
如何根据WPF中的情况自定义菜单? 我有一个带有基本菜单的主窗口。在这个窗口中,我可以加载不同的用户控件,然后我希望根据使用的用户控件使用不同的菜单选项来扩展菜单 例如:C# 根据WPF中的情况自定义菜单,c#,wpf,xaml,mvvm,binding,C#,Wpf,Xaml,Mvvm,Binding,如何根据WPF中的情况自定义菜单? 我有一个带有基本菜单的主窗口。在这个窗口中,我可以加载不同的用户控件,然后我希望根据使用的用户控件使用不同的菜单选项来扩展菜单 例如: Main menu: File Open - MRU - Exit For viewing of UserControl 1: File Open Edit - MRU - Exit For viewing of UserControl 2: File
Main menu:
File
Open
-
MRU
-
Exit
For viewing of UserControl 1:
File
Open
Edit
-
MRU
-
Exit
For viewing of UserControl 2:
File
Open
Edit
-
MRU
-
Exit
View
Show codes
Show capital letters
In Editing
File
Open
Save
Save as...
-
MRU
-
Exit
Edit
Add
Remove
Move
-
Cancle Edit
我会将菜单绑定到一个集合,并让不同的UserControls在加载时更改集合 编辑-下面是一个示例 您的主视图将包含以下内容
<Menu ItemsSource="{Binding Path=CurrentUserControl.MenuItems}">
<Menu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding MenuItemText}" />
<Setter Property="Command" Value="{Binding MenuItemCommand}" />
<Setter Property="CommandParameter" Value="{Binding MenuItemCommandParameter}" />
</Style>
</Menu.Resources>
</Menu>
公共可观察收集菜单项;
我会将菜单绑定到一个集合,并让不同的用户控件在加载时更改集合
编辑-下面是一个示例
您的主视图将包含以下内容
<Menu ItemsSource="{Binding Path=CurrentUserControl.MenuItems}">
<Menu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding MenuItemText}" />
<Setter Property="Command" Value="{Binding MenuItemCommand}" />
<Setter Property="CommandParameter" Value="{Binding MenuItemCommandParameter}" />
</Style>
</Menu.Resources>
</Menu>
公共可观察收集菜单项;
我确实找到了一个解决方案:
但是应该有更好的办法我确实找到了解决办法:
但是应该有更好的方法如何将某些菜单选项的可见性绑定到ViewModel中的布尔值,并使用IValueConverter在可见和折叠之间切换?如何将某些菜单选项的可见性绑定到ViewModel中的布尔值,使用IValueConverter在可见和折叠之间切换?您可以使用CompositeCollection将多个集合合并为一个集合。 以下示例来自:
您可以使用CompositeCollection将多个集合合并为一个集合。 以下示例来自:
一个简单的方法是在代码隐藏中构建一系列if-then构造,根据用户控件可见的内容更改各种菜单项的可见性。一个简单的方法是在代码隐藏中构建一系列if-then构造,更改各种菜单项的可见性,取决于哪些用户控件是可见的。但是ui是从破坏MVVM的ViewModel创建的。菜单应该在相应用户控件的视图中,并且以任何方式与主程序中的菜单合并。您仍然可以在视图中创建菜单,但是,您可以将它们绑定到ViewModel中定义的ItemsSource,而不是在视图中手动构建菜单项。我不确定我是否真正理解您的意思。是的,我创建了视图的主菜单,但它的自定义是在视图模型中完成的。@magol我在回答中添加了一些示例代码。我没有时间做一个完整的模型,但我希望这将为您指明正确的方向。这个答案是一个非常好的方法,并且完全符合MVVM。视图模型是视图的抽象。填充菜单的组件应来自该视图的ViewModel。正如Rachel指出的,每个控件的ViewModel都有一组菜单选项,菜单控件可以绑定到这些选项。切换控件时,必须确保对“CurrentUserControl.MenuItems”调用OnPropertyChanged。但是,ui是从断开MVVM的ViewModel创建的。菜单应该在相应用户控件的视图中,并且以任何方式与主程序中的菜单合并。您仍然可以在视图中创建菜单,但是,您可以将它们绑定到ViewModel中定义的ItemsSource,而不是在视图中手动构建菜单项。我不确定我是否真正理解您的意思。是的,我创建了视图的主菜单,但它的自定义是在视图模型中完成的。@magol我在回答中添加了一些示例代码。我没有时间做一个完整的模型,但我希望这将为您指明正确的方向。这个答案是一个非常好的方法,并且完全符合MVVM。视图模型是视图的抽象。填充菜单的组件应来自该视图的ViewModel。正如Rachel指出的,每个控件的ViewModel都有一组菜单选项,菜单控件可以绑定到这些选项。切换控件时,必须确保对“CurrentUserControl.MenuItems”调用OnPropertyChanged,但所有菜单都在主窗口中编码。如果我想添加一个视图,那么我还必须更改主视图。最近我可能与IValueConverter合作太多了。。。也许您可以创建一个以菜单为参数的转换器,将菜单“转换”为参数和值之间的合并?然后,主窗口菜单绑定到usercontrol菜单,菜单资源作为转换器参数。缺点是您必须在参考资料中编辑主窗口菜单。它一点也不漂亮。但是所有的菜单都在主窗口中编码。如果我想添加一个视图,那么我还必须更改主视图。最近我可能与IValueConverter合作太多了。。。也许您可以创建一个以菜单为参数的转换器,将菜单“转换”为参数和值之间的合并?然后,主窗口菜单绑定到usercontrol菜单,菜单资源作为转换器参数。缺点是您必须在参考资料中编辑主窗口菜单。而且一点也不漂亮。
public ObservableCollection<MenuItem> MenuItems;
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Grid Background="Transparent">
<Grid.Resources>
<x:Array Type="{x:Type sys:Object}" x:Key="extensions">
<Separator />
<MenuItem Header="Extension MenuItem 1" />
<MenuItem Header="Extension MenuItem 2" />
<MenuItem Header="Extension MenuItem 3" />
</x:Array>
</Grid.Resources>
<Grid.ContextMenu>
<ContextMenu>
<ContextMenu.ItemsSource>
<CompositeCollection>
<MenuItem Header="Standard MenuItem 1" />
<MenuItem Header="Standard MenuItem 2" />
<MenuItem Header="Standard MenuItem 3" />
<CollectionContainer Collection="{StaticResource extensions}" />
</CompositeCollection>
</ContextMenu.ItemsSource>
</ContextMenu>
</Grid.ContextMenu>
</Grid>
</Window>