繁体   English   中英

Microsoft PRISM:在WPF菜单控件中使用多个区域

[英]Microsoft PRISM: Using multiple regions in a WPF Menu control

我们正在PRISM和大量模块的帮助下实施模块化软件。 该框架包含MainWindow Shell,在其中定义了工具栏和菜单。 例如,每个模块在初始化时,每个模块都应能够在运行时添加自己的工具栏和菜单条目。 为此,使用区域管理器。 对于工具栏,它运行良好,但是对于菜单,几乎没有问题发生:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>

    <!--
        <Menu Grid.Row="0" IsMainMenu="True">
        <MenuItem Header="Test" />
        </Menu>
    -->
    <!--  Main Menu  -->
    <StackPanel Grid.Row="0" Orientation="Horizontal">


        <ItemsControl Name="MainMenuRegion" prism:RegionManager.RegionName="{x:Static common:RegionNames.MainMenu}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
        <ItemsControl Name="AppMenuRegion" prism:RegionManager.RegionName="{x:Static common:RegionNames.AppMenu}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>


        <ItemsControl Name="HelpMenuRegion" prism:RegionManager.RegionName="{x:Static common:RegionNames.HelpMenu}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>

    </StackPanel>

.....

区域RegionNames.MainMenu用于诸如File,Edit, RegionNames.MainMenu之类的常用条目。 Region RegionNames.AppMenu用于多个模块,以添加其自己的菜单。 区域RegionNames.HelpMenu用于公共条目“窗口”和“帮助”。 使用区域的动机是获得菜单项的订单。 每个模块都以这种方式为菜单创建自己的视图(用户控件)和视图模型:

<Menu ItemsSource="{Binding MainMenuItems}" />

此外,对于菜单项,我们使用数据模板:

<Style TargetType="{x:Type MenuItem}">
    <Setter Property="Command" Value="{Binding Command}" />
    <Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
    <Setter Property="Header" Value="{Binding Text, UpdateSourceTrigger=PropertyChanged}" />
    <Setter Property="IsChecked" Value="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}" />
    <Setter Property="IsEnabled" Value="{Binding IsEnabled, UpdateSourceTrigger=PropertyChanged}" />
    <Setter Property="Visibility" Value="{Binding IsVisible, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource VisibilityConverter}}" />
    <Setter Property="ItemsSource" Value="{Binding Children, UpdateSourceTrigger=PropertyChanged}" />
    <Setter Property="Icon" Value="{DynamicResource itemIcon}" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsSeparator, UpdateSourceTrigger=PropertyChanged}" Value="true">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Separator />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </DataTrigger>
        <DataTrigger Binding="{Binding Icon}" Value="{x:Null}">
            <Setter Property="Icon" Value="{x:Null}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

但是这种方法行不通。 尝试在两个不同的区域中注册相同的视图时,如下所示:

IRegionViewRegistry regionViewRegistry = ServiceLocator.Current.GetInstance<IRegionViewRegistry>();
regionViewRegistry.RegisterViewWithRegion(RegionNames.HelpMenu, typeof(MainMenu));
regionViewRegistry.RegisterViewWithRegion(RegionNames.MainMenu, typeof(MainMenu));

只有最后一个区域(MainMenu区域)将获得菜单项。 在两个不同的视图中,行为相同。 似乎最后一个覆盖了第一个。

我搜索了合适的解决方案,但不幸的是,直到现在,我还没有找到适合该用例的解决方案。 希望我会以这种方式找到解决该问题的解决方案或其他方法。 提前致谢。

IRegionViewRegistry regionViewRegistry = ServiceLocator.Current.GetInstance<IRegionViewRegistry>();
regionViewRegistry.RegisterViewWithRegion(RegionNames.HelpMenu, typeof(MainMenu)); // registering same view with diferent region 
regionViewRegistry.RegisterViewWithRegion(RegionNames.MainMenu, typeof(MainMenu));

如果我理解正确,则可以定义3个区域(可以在其中添加自定义用户控件的占位符是菜单项。)

1)RegionNames.HelpMenu

2)RegionNames。 应用菜单

3)RegionNames.MainMenu

现在,您需要创建3个自定义用户控件并将其注册到区域中。

 public partial class MainMenuSelection : UserControl 
    {
       public MainMenuSelection () 
       { 
         InitializeComponent();
       } 
    }

应用菜单和帮助菜单分别类似

然后你可以使用像

ServiceLocator.Current.GetInstance<IRegionViewRegistry>();
regionViewRegistry.RegisterViewWithRegion(RegionNames.HelpMenu,typeof(HelpMenuSelection));
regionViewRegistry.RegisterViewWithRegion(RegionNames.MainMenu, typeof(MainMenuSelection)); // You are registering view (mainmenuselection) with unique region placeholder(RegionNames.MainMenu)

感谢您的回答。 但是我是这样描述的

    IRegionViewRegistry regionViewRegistry = ServiceLocator.Current.GetInstance<IRegionViewRegistry>();
    regionViewRegistry.RegisterViewWithRegion(RegionNames.MainMenu, typeof(MainMenu));
    regionViewRegistry.RegisterViewWithRegion(RegionNames.HelpMenu, typeof(HelpMenu));

和例如菜单项的用户控件

<UserControl x:Class="XXX.GUI.View.MainMenu"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         d:DesignHeight="300"
         d:DesignWidth="300"
         mc:Ignorable="d">

     <MenuItem ItemsSource="{Binding MainMenuItems}" /> 
</UserControl>

在我的ViewModel中,创建了MainMenuItems的可观察集合。 当我以这种方式执行操作时,MenuItem不是顶层,而是第二层,并且无法将“帮助”菜单注入“帮助”菜单区域。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM