WPF ContextMenu itemtemplate, пункт меню внутри элемента меню
У меня есть следующий xaml:
<ContextMenu ItemsSource="{Binding TestItems}">
<ContextMenu.ItemTemplate>
<DataTemplate DataType="models:TestItemModel">
<MenuItem IsChecked="{Binding IsSelected}" Header="{Binding Header}" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
Класс TestItemModel состоит только из логического свойства IsSelected и свойства Header string.
TestItems представляет собой список TestItemModels.
Данные привязываются к контекстному меню, но они отражаются в пользовательском интерфейсе как MenuItem внутри MenuItem (с дополнительными полями как таковыми, что делает меню очень большим). Я могу исправить это, изменив MenuItem внутри DataTemplate на TextBox, но затем я больше не могу связывать IsSelected (что мне нужно для свойств визуализации).
У меня есть пара вопросов по этому поводу:
- Почему MenuItem внутри MenuItem? Это не имеет смысла для меня, так как он связан не со списком пунктов меню, а со списком TestItemModels.
- Как я могу решить это?
1 ответ
Так как MenuItem
это тип контейнера, и когда он переводит вашу модель представления в визуальный элемент, он оборачивает ваш шаблон в MenuItem
, Таким же образом ListBox
создаст ListBoxItem
или же ListView
буду использовать ListViewItem
, Для привязки свойств оболочки вам нужно использовать ItemContainerStyle
<ContextMenu ItemsSource="{Binding TestItems}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="IsChecked" Value="{Binding IsSelected}"/>
<Setter Property="Header" Value="{Binding Header}"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
или, если вы предпочитаете, вы можете сделать это частично с ItemTemplate
а также ItemContainerStyle
<ContextMenu ItemsSource="{Binding TestItems}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
</ContextMenu.ItemTemplate>
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="IsChecked" Value="{Binding IsSelected}"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
В этом сценарии все, что есть в ItemTemplate
станет MenuItem.Header
но IsChecked
собственность все еще должна быть связана в ItemContainerStyle