Menu in the form of prism areas + problem with themes

I am using a menu control as a region. It works fine, however, when I add a theme to my application (a resource dictionary has been added to my App.xaml), ordinary menus have a theme, but this theme is missing in the views inside my region (which have menu items).

What could be the reason for this? Anyone have an idea for a job?

Alex

+3
source share
3 answers

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

WPF - DataTemplate

WPF-

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

MenuService 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 Karl :

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
+5

Prism. CodePlex.

+1

.

0

Source: https://habr.com/ru/post/1778958/


All Articles