Я бы хотел связать ItemsSource
из ContextMenu
с коллекцией в моей модели представления, и я бы хотел, чтобы ContextMenu
также показывал Separator
с.
Обычно Separator
в ContextMenu
отображается как горизонтальная линия. Но это не работает в моем случае. Может быть, вы можете пролить свет на это?
Я знаю, что модели представлений должны реализовывать INotifyPropertyChanged
, но для простоты я отбросил свой пример всего ненужного.
MenuItemViewModel.vb:
Public Class MenuItemViewModel
Public Property IsSeparator As Boolean
Public Property Caption As String
End Class
MainViewModel.vb:
Public Class MainViewModel
Private ReadOnly _items As List(Of MenuItemViewModel)
Public Sub New()
_items = New List(Of MenuItemViewModel)
_items.Add(New MenuItemViewModel With {.Caption = "Item 1"})
_items.Add(New MenuItemViewModel With {.IsSeparator = True, .Caption = "Sep 1"})
_items.Add(New MenuItemViewModel With {.Caption = "Item 2"})
_items.Add(New MenuItemViewModel With {.Caption = "Item 3"})
_items.Add(New MenuItemViewModel With {.IsSeparator = True, .Caption = "Sep 2"})
_items.Add(New MenuItemViewModel With {.Caption = "Item 4"})
End Sub
Public ReadOnly Property Items As List(Of MenuItemViewModel)
Get
Return _items
End Get
End Property
End Class
MenuItemTemplateSelector.vb:
Public Class MenuItemTemplateSelector
Inherits DataTemplateSelector
Public Property ItemTemplate As DataTemplate
Public Property SeparatorTemplate As DataTemplate
Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate
Dim menuItem As MenuItemViewModel
menuItem = TryCast(item, MenuItemViewModel)
If (menuItem IsNot Nothing) AndAlso menuItem.IsSeparator Then
Return Me.SeparatorTemplate
Else
Return Me.ItemTemplate
End If
End Function
End Class
MainWindow.xaml:
<Window x:Class="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:WpfApp3"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:MainViewModel, IsDesignTimeCreatable=True}"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Key="mit">
<TextBlock Text="{Binding Caption}" />
</DataTemplate>
<DataTemplate x:Key="mst">
<Separator />
<!--<Separator Style="{StaticResource {x:Static MenuItem.SeparatorStyleKey}}" />-->
</DataTemplate>
<local:MenuItemTemplateSelector x:Key="mits"
ItemTemplate="{StaticResource mit}"
SeparatorTemplate="{StaticResource mst}" />
</Window.Resources>
<Grid>
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Text="Right click me">
<TextBox.ContextMenu>
<ContextMenu ItemsSource="{Binding Items}" ItemTemplateSelector="{StaticResource mits}" />
</TextBox.ContextMenu>
</TextBox>
</Grid>
</Window>
Если вы щелкнете правой кнопкой мыши по TextBox
, всплывет ContextMenu
, но Separator
не будут отображаться как горизонтальные линии, вместо этого они выглядят как обычные пункты меню, но без заголовка. Они даже синего цвета, когда мышь парит над ними.
Поскольку у них есть заголовок в модели представления, и этот заголовок не отображается, кажется, что он действительно не использует определенный ItemTemplate
, но какой шаблон он использует? Или простой <Separator />
больше не создает горизонтальную линию?)
Как я могу получить разделитель по умолчанию, чтобы показать?
Редактировать: Кажется, что мой Separator
обернут внутри MenuItem
, но как мне этого избежать?