菜单作为棱镜区域 + 主题问题 [英] Menu as prism regions + themes problem

查看:66
本文介绍了菜单作为棱镜区域 + 主题问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Menu 控件作为区域.它工作正常,但是当我向我的应用程序添加一个主题时(向我的 App.xaml 添加了一个资源字典)普通菜单有这个主题,但是我区域内的视图(菜单项)没有这个主题.

I am using a Menu control as a region. It works fine, however when I add a theme to my application (Added a resource-dictionary to my App.xaml) normal menus have the theme, but the views inside my region (which are menu-items) don't have this theme.

这背后的原因可能是什么?有人有解决方法的想法吗?

What might be the reason behind it? Anybody has an idea for a work-around?

亚历克斯.

推荐答案

问题在于,当在 MenuItem 中使用该区域时,该区域的 ItemsControl 会设置样式,但其子项不会设置样式.我通过使用来自各种来源的动态菜单找到了一种解决方法:

The problem is that the ItemsControl of the region gets styled but its children do not when the region is used inside a MenuItem. I found a workaround by using dynamic menus from various sources:

WPF 示例系列 – 数据绑定HierarchicalDataTemplate 菜单示例

使用 HierarchicalDataTemplate 构建数据绑定 WPF 菜单

我在基础结构项目中创建了 IMenuService 和 MenuItemViewModel,在我的 Shell 项目中实现了 IMenuService,并在我的模块中使用 IMenuService 添加菜单.

I created an IMenuService and MenuItemViewModel in my Infrastructure project, implement the IMenuService in my Shell project, and use IMenuService in my module to add a menu.

public interface IMenuService
{
    List<MenuItemViewModel> Menu { get; set; }
    MenuItemViewModel FileMenu { get; set; }
}

public class MenuItemViewModel : NotificationObject
{
    private string _header;
    private bool _isEnabled = true;
    private ICommand _command;
    private Image _icon;
    private string _inputGestureText;
    private ObservableCollection<MenuItemViewModel> _children;

    public MenuItemViewModel()
    {
        Children = new ObservableCollection<MenuItemViewModel>();
    }

    public MenuItemViewModel(bool isSeparator) : this()
    {
        _isSeparator = isSeparator;
    }

    public string Header
    {
        get { return _header; }
        set
        {
            _header = value;
            RaisePropertyChanged("Header");
        }
    }

    public bool IsEnabled
    {
        get { return _isEnabled; }
        set
        {
            _isEnabled = value;
            RaisePropertyChanged("IsEnabled");
        }
    }

    public ICommand Command
    {
        get { return _command; }
        set
        {
            _command = value;
            RaisePropertyChanged("Command");
        }
    }

    public Image Icon
    {
        get { return _icon; }
        set
        {
            _icon = value;
            RaisePropertyChanged("Icon");
        }
    }

    public string InputGestureText
    {
        get { return _inputGestureText; }
        set
        {
            _inputGestureText = value;
            RaisePropertyChanged("InputGestureText");
        }
    }

    public ObservableCollection<MenuItemViewModel> Children
    {
        get { return _children; }
        set { _children = value; }
    }

    private bool _isSeparator;
    public bool IsSeparator
    {
        get { return _isSeparator; }
        set { _isSeparator = value; }
    }
}

Shell 项目中的 MenuService:

MenuService in Shell project:

[Export(typeof(IMenuService))]
public class MenuService : IMenuService
{
    [ImportingConstructor]
    public MenuService()
    {
        _menu = new List<MenuItemViewModel>();
        _fileMenu = new MenuItemViewModel {Header = "_File"};
        _fileMenu.Children.Add(new MenuItemViewModel { Header = "_New" });
        _fileMenu.Children.Add(new MenuItemViewModel(true)); // Separator

        _menu.Add(_fileMenu);
    }

    private static Image CreateImage(string url)
    {
        var image = new Image
                        {
                            Source = new BitmapImage(new Uri("Resources/" + url, UriKind.Relative)),
                            Height = 16,
                            Width = 16
                        };
        RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.NearestNeighbor);
        return image;
    }

    private List<MenuItemViewModel> _menu;
    public List<MenuItemViewModel> Menu
    {
        get { return _menu; }
        set { _menu = value; }
    }

    private MenuItemViewModel _fileMenu;
    public MenuItemViewModel FileMenu
    {
        get { return _fileMenu; }
        set { _fileMenu = value; }
    }
}

在 Shell.xaml 中

In Shell.xaml

<Window.Resources>
    <Style TargetType="{x:Type MenuItem}" x:Key="separatorStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type MenuItem}">
                    <Separator HorizontalAlignment="Stretch" IsEnabled="False"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style BasedOn="{StaticResource {x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
        <Setter Property="Command" Value="{Binding Command}"/>
        <Setter Property="Icon" Value="{Binding Icon}"/>
        <Setter Property="InputGestureText" Value="{Binding InputGestureText}"/>
        <Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
    </Style>

    <HierarchicalDataTemplate DataType="{x:Type infrastructure:MenuItemViewModel}" ItemsSource="{Binding Path=Children, UpdateSourceTrigger=PropertyChanged}">
        <ContentPresenter Content="{Binding Header}" RecognizesAccessKey="True" />
    </HierarchicalDataTemplate>

    <local:SeparatorStyleSelector x:Key="separatorStyleSelector"/>

在 ShellViewModel 中:

In the ShellViewModel:

[ImportingConstructor]
    public ShellViewModel(IMenuService menuService)
    {
        Menu = menuService.Menu.ToObservableCollection();
    }

    private ObservableCollection<MenuItemViewModel> _menu = new ObservableCollection<MenuItemViewModel>();
    public ObservableCollection<MenuItemViewModel> Menu
    {
        get { return _menu; }
        set
        {
            _menu = value;
            RaisePropertyChanged("MenuItems");
        }
    }

从模块添加菜单:

[ModuleExport(typeof(OptionModule))]
public class OptionModule : IModule
{
    [ImportingConstructor]
    public OptionModule(IMenuService menuService)
    {
        menuService.ToolsMenu.Children.Add(new MenuItemViewModel {Header = "Options", Command = OptionCommand});
    }
}

这是来自上面 Karl 站点的 SeparatorStyleSelector:

Here is the SeparatorStyleSelector from Karl's site above:

public override Style SelectStyle(object item, DependencyObject container)
    {
        if (((MenuItemViewModel)item).IsSeparator)
        {
            return (Style) ((FrameworkElement) container).FindResource("separatorStyle");
        }
        return base.SelectStyle(item, container);
    }
enter code here

这篇关于菜单作为棱镜区域 + 主题问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆