Стиль элемента WPF ContextMenu не применяется в MVVM - PullRequest
0 голосов
/ 05 марта 2020

У меня есть приложение WPF с контекстным меню на основе MVVM. Элементы контекстного меню могут быть добавлены динамически через соответствующую модель представления. Мой вид выглядит так:

<Window x:Class="WpfApp11.MainWindow"
        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"
        xmlns:local="clr-namespace:WpfApp11"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>

        <ResourceDictionary>

            <Style TargetType="{x:Type MenuItem}" x:Key="MyItemStyle">
                <Setter Property="Header" Value="{Binding Header}"/>
            </Style>

            <HierarchicalDataTemplate x:Key="MyItemContainer" 
                                      DataType="{x:Type local:MenuItemViewModel}" 
                                      ItemsSource="{Binding MenuItems}">
            </HierarchicalDataTemplate>


            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/WpfApp11;component/Resources/Images.xaml" />
            </ResourceDictionary.MergedDictionaries>

        </ResourceDictionary>
    </Window.Resources>

    <Border BorderBrush="Blue" BorderThickness="3">
        <Grid>
            <Button Width="100" Height="30">
                <Button.ContextMenu>
                    <ContextMenu ItemsSource="{Binding MeasurementContextMenu}" 
                                 ItemContainerStyle="{StaticResource MyItemStyle}"
                                 ItemTemplate="{StaticResource MyItemContainer}"/>
                </Button.ContextMenu>
            </Button>
        </Grid>
    </Border>
</Window>

Модель вида выглядит так:

public class MainModel : INotifyPropertyChanged
{

    public MainModel()
    {
        Initialize();
    }

    private void Initialize()
    {
        var first = new MenuItemViewModel("Just a test");
        var second = new MenuItemViewModel("Second");
        first.MenuItems.Add(second);
        MeasurementContextMenu.Add(first);
    }

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

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

И модель вида для пунктов меню:

public class MenuItemViewModel : INotifyPropertyChanged
{
    #region Fields

    private string _header;

    #endregion Fields

    #region Constructors

    public MenuItemViewModel(string header)
    {
        Header = header;
    }

    #endregion Constructors

    #region Properties

    public string Header
    {
        get
        {
            return _header;
        }
        set
        {
            if(_header != value)
            {
                _header = value;
                OnPropertyChanged();
            }
        }
    }

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

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion Properties
}

Итак иерархическая структура работает, как и ожидалось, но применяемый стиль не работает. Таким образом, элементы появляются, но без текста. Кажется, это свойство не имеет никакого влияния

ItemContainerStyle="{StaticResource MyItemStyle}"

Как стиль может быть применен в этом случае?

1 Ответ

1 голос
/ 05 марта 2020

Избавьтесь от ItemContainerStyle:

<ContextMenu ItemsSource="{Binding MeasurementContextMenu}" 
             ItemTemplate="{StaticResource MyItemContainer}"/>

... и поместите TextBlock, который связывается с Header в HierarchicalDataTemplate:

<HierarchicalDataTemplate x:Key="MyItemContainer" 
                          DataType="{x:Type local:MenuItemViewModel}" 
                          ItemsSource="{Binding MenuItems}">
    <TextBlock Text="{Binding Header}" />
</HierarchicalDataTemplate>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...