我想将ItemsSource
的{{1}}绑定到视图模型中的集合,并且我希望ContextMenu
也显示ContextMenu
通常,Separator
中的Separator
呈现为一条水平线。但这似乎不适用于我的情况。也许您可以对此有所了解?
我知道视图模型应该实现ContextMenu
,但是为了简单起见,我剥离了所有不必要内容的示例。
MenuItemViewModel.vb:
INotifyPropertyChanged
MainViewModel.vb:
Public Class MenuItemViewModel
Public Property IsSeparator As Boolean
Public Property Caption As String
End Class
MenuItemTemplateSelector.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
MainWindow.xaml:
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
如果您右键单击<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
里面了,但是我该如何避免呢?
答案 0 :(得分:0)
根据Ed Plunkett的评论,我删除了“ MenuItemTemplateSelector.vb”文件和所有相应的窗口资源(“ mit”,“ mst”和“ mits”)。
然后我添加了以下新窗口资源...
<ControlTemplate x:Key="mist" TargetType="{x:Type MenuItem}">
<Separator />
</ControlTemplate>
<ControlTemplate x:Key="mict" TargetType="{x:Type MenuItem}">
<MenuItem Header="{Binding Caption}" />
</ControlTemplate>
<Style x:Key="cmics" TargetType="{x:Type MenuItem}">
<Setter Property="Template" Value="{StaticResource mict}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSeparator}" Value="True">
<Setter Property="Template" Value="{StaticResource mist}" />
</DataTrigger>
</Style.Triggers>
</Style>
...并将我的TextBox
更改为...
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Text="Right click me">
<TextBox.ContextMenu>
<ContextMenu ItemsSource="{Binding Items}" ItemContainerStyle="{StaticResource cmics}" />
</TextBox.ContextMenu>
</TextBox>
...一切正常。
谢谢Ed Plunkett。