菜单作为棱镜区域+主题问题

时间:2010-12-07 13:18:41

标签: wpf prism

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

背后可能是什么原因?任何人都有一个解决方法的想法?

亚历。

3 个答案:

答案 0 :(得分:5)

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

WPF Sample Series – Databound HierarchicalDataTemplate Menu Sample

Building a Databound WPF Menu Using a HierarchicalDataTemplate

我在我的Infrastructure项目中创建了一个IMenuService和MenuItemViewModel,在我的Shell项目中实现了IMenuService,并在我的模块中使用IMenuService来添加一个菜单。

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:

[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

<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中:

[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:

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

答案 1 :(得分:1)

它可能是Prism Menu区域适配器中的错误。我建议在CodePlex上报告问题。

答案 2 :(得分:0)

我只是迭代子控件并明确地为每个控件分配主题。