C# 如何在最后一个元素之前使用分隔符定义WPF ContextMenu,使用ItemsSource上的绑定而不是单个MenuItems

C# 如何在最后一个元素之前使用分隔符定义WPF ContextMenu,使用ItemsSource上的绑定而不是单个MenuItems,c#,.net,wpf,xaml,mvvm,C#,.net,Wpf,Xaml,Mvvm,我正在尝试创建一个ContextMenu,该菜单通过可检查的MenuItems定义一些过滤器,并使用分隔符将最后一个MenuItem与以前的分隔 我知道我可以用以下方式定义和管理菜单项s和分隔符: <ContextMenu HasDropShadow="False" Placement="Bottom"> <MenuItem IsCheckable="True" IsChecked="{Binding

我正在尝试创建一个
ContextMenu
,该菜单通过可检查的
MenuItem
s定义一些过滤器,并使用
分隔符将最后一个
MenuItem
与以前的分隔

我知道我可以用以下方式定义和管理
菜单项
s和
分隔符

<ContextMenu HasDropShadow="False" Placement="Bottom">
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked1}" Header="Filter 1"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked2}" Header="Filter 2"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked3}" Header="Filter 3"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked4}" Header="Filter 4"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked5}" Header="Filter 5"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked6}" Header="Filter 6"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked7}" Header="Filter 7"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked8}" Header="Filter 8"/>
    <Separator Styles.Separator="Default"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked9}" Header="Active"/>
</ContextMenu>

但我宁愿尝试避免在我的ViewModel中检查9
IsChecked
属性,而不是让下一个开发人员在需要添加/删除筛选器时添加/删除
MenuItem
及其关联属性

我更愿意做的是使用
ContextMenu
ItemsSource
属性,为
ItemsSource
的每个元素定义一个
itemstemplate
。不幸的是,如果我这样做,我不知道如何在
ItemsSource
的最后一个元素之前定义
分隔符


有没有一种方法可以实现我想要的功能,而无需在ViewModel中手动定义每个
MenuItem
及其相关属性?

基于以下答案:

我找到了一种混合方法来实现我想要实现的目标,这在我的上下文中是有意义的:我需要手动添加的唯一
MenuItem
是最后一个,我需要在ViewModel中以不同的方式处理它,所以我不介意手动添加那个。但是,所有其他过滤器都是根据我的
所有过滤器自动生成的,不包括Astone
可观察到的收集

<UserControl.Resources>
    <CollectionViewSource x:Key="AllFiltersExceptTheLastOne" Source="{Binding Path=Filters}"/>
</UserControl.Resources>
...
<Button.ContextMenu>
    <ContextMenu HasDropShadow="False" Placement="Bottom">
        <ContextMenu.ItemsSource>
            <CompositeCollection>
                <CollectionContainer Collection="{Binding Source={StaticResource AllFiltersExceptTheLastOne}}" />
                <Separator Margin="0,5,0,5" Styles.Separator="Default"/>
                <MenuItem Padding="2,2,2,2" IsCheckable="true" IsChecked="{Binding Path=Filter.IsChecked}" Header="{Binding Path=Filter.Status}" />
             </CompositeCollection>
         </ContextMenu.ItemsSource>
         <ContextMenu.ItemContainerStyle>
             <Style>
                 <Setter Property="MenuItem.Padding" Value="2,2,2,2"/>
                 <Setter Property="MenuItem.IsCheckable" Value="true"/>
                 <Setter Property="MenuItem.Header" Value="{Binding Path=Status}"/>
                 <Setter Property="MenuItem.IsChecked" Value="{Binding Path=IsChecked}"/>
             </Style>
         </ContextMenu.ItemContainerStyle>
     </ContextMenu>
</Button.ContextMenu>

...

您的问题不清楚。从根本上说,您必须在某个时候操作源集合本身,因为如果绑定
ItemsSource
,则无法直接修改
ItemsControl
集合。但是你的问题中没有足够的信息来知道什么方法是好的。理想情况下,绑定源集合可以容纳分隔符的标记,然后分隔符将使用不同的模板。如果这不起作用,您可能必须将原始集合包装成一个插入适当标记的集合。请改进这个问题。请参阅和。根据
项源
方法,很容易区分
菜单项
分隔符
。你只需要先尝试一下,然后用非工作代码提问。请参阅此处未标记为答案的帖子:@PeterDuniho我不知道如何根据你提供的链接更清楚。我想我的标题已经足够清楚了,我提供了一个代码片段,以我认为不可接受的方式实现了我想要实现的目标,原因我已经列出(但它确实有效),我建议我可以使用
ItemsSource
作为生成
MenuItem
的替代方法(当然,我可以为此粘贴一个代码段,但我没有)这会导致一个我不知道如何解决的问题(我不知道如何以这种方式引入分隔符)。