经过多次尝试,我终于找到了一个适合我的解决方案。不幸的是,它包含了许多针对不同内容的变通方法,并不是一个非常直接的解决方案。我不敢相信创建一个简单的contextmenu这么难。
如前所述,我无法使用datatemplate,因为这将导致由分隔符引起的异常,分隔符未实现某些属性,例如
IsCheckable
ContextMenu.ItemContainerStyle
到
ContextMenu.Resources
仅适用于真实菜单项
(见H.B.的答案
https://stackoverflow.com/a/18948356/5381620
)
<ContextMenu>
<ContextMenu.Resources>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Name}"/>
<Setter Property="IsCheckable" Value="{Binding IsCheckable}"/>
<Setter Property="IsChecked" Value="{Binding IsChecked}"/>
<Setter Property="Command" Value="{Binding Cmd}"/>
<!-- this is necessary to avoid binding error, see explanation below-->
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
<!-- collectionViewSource necessary for behavior described here
https://social.msdn.microsoft.com/Forums/vstudio/en-US/b15cbd9d-95aa-47c6-8068-7ae9f7dca88a/collectioncontainer-does-not-support-relativesource?forum=wpf
-->
<CollectionViewSource x:Key="MenuCmds" Source="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path= DataContext.CmdObsColl}"/>
<CollectionViewSource x:Key="MenuCheckable" Source="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path= DataContext.CheckableObsCol}"/>
</ContextMenu.Resources>
<ContextMenu.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource MenuCmds}}"/>
<Separator />
<CollectionContainer Collection="{Binding Source={StaticResource MenuCheckable}}"/>
</CompositeCollection>
</ContextMenu.ItemsSource>
</ContextMenu>
https://social.msdn.microsoft.com/Forums/vstudio/en-US/42cd1554-de7a-473b-b977-ddbd6298b3d0/binding-error-when-using-compositecollection-for-menuitems?forum=wpf
我仍然不明白的是,如果我只在应用程序中设置ContentAlignment,为什么仍然会出现绑定错误。资源或上下文。资源。出于某种原因,有必要同时设置这两个参数。如果有人能给我解释一下,我会很高兴的。
<Application.Resources>
<Style TargetType="MenuItem">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
</Application.Resources>
对于绑定,我使用了一些MenuItemVM类,或多或少类似于此,我可以根据menuitem是可检查的还是命令来设置属性。
class ContextMenuItemVM
{
public string Name { get; }
public bool IsCheckable { get; }
public bool IsChecked { get; set; }
public ICommand Cmd { get; }
}