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中检查9IsChecked
属性,而不是让下一个开发人员在需要添加/删除筛选器时添加/删除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
的替代方法(当然,我可以为此粘贴一个代码段,但我没有)这会导致一个我不知道如何解决的问题(我不知道如何以这种方式引入分隔符)。