Меню как призма регионов + тема проблем - PullRequest
3 голосов
/ 07 декабря 2010

Я использую элемент управления меню в качестве региона.Это работает нормально, однако, когда я добавляю тему в свое приложение (добавлен словарь ресурсов в мой App.xaml), обычные меню имеют тему, но представления внутри моего региона (которые являются пунктами меню) не имеют этой темы.

В чем может быть причина этого?У кого-нибудь есть идея для обхода?

Алекс.

Ответы [ 3 ]

5 голосов
/ 11 марта 2011

Проблема в том, что ItemsControl региона получает стиль, а его дочерние элементы - нет, когда регион используется внутри MenuItem. Я нашел обходной путь, используя динамические меню из различных источников:

Серия примеров WPF - Пример меню HierarchicalDataTemplate с привязкой к данным

Создание WPF-меню с привязкой к данным с использованием шаблона HierarchicalDataTemplate

Я создал IMenuService и MenuItemViewModel в своем проекте инфраструктуры, внедрил IMenuService в моем проекте Shell и использую 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:

[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});
    }
}

Вот 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 голос
/ 07 декабря 2010

Это может быть ошибка в адаптере региона меню Prism.Я бы предложил сообщить о проблеме на CodePlex.

0 голосов
/ 07 декабря 2010

Я бы просто повторил дочерние элементы управления и явно назначил тему каждому из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...