具有ItemsSource和Separators的ContextMenu

时间:2019-05-23 06:53:55

标签: wpf

我想将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里面了,但是我该如何避免呢?

1 个答案:

答案 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