WPF DataGrid:将DataGridColumn绑定到ContextMenu MenuItems IsChecked(MVVM)

Fub*_*zot 8 wpf xaml binding datagrid mvvm

我想通过右键单击列标题来控制用户可用的DataGrid列可见性ContextMenu.将ContextMenu显示所有可用的列的名称.我正在使用MVVM设计模式.

我的问题是:如何将绑定DataGridColumnVisibility属性设置IsChecked的属性MenuItem地处ContextMenu.

一些模型代码:

<UserControl.Resources>         
    <ContextMenu x:Key="ColumnHeaderContextMenu">  
        <MenuItem Header="Menu Item..1" IsCheckable="True" />  
    </ContextMenu>  
    <Style x:Key="ColumnHeaderStyle" 
           TargetType="{x:Type toolkit:DataGridColumnHeader}">  
        <Setter Property="ContextMenu" 
                Value="{StaticResource ColumnHeaderContextMenu}" />  
    </Style>  
    <BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" />  
</UserControl.Resources>  
Run Code Online (Sandbox Code Playgroud)

... flaf flaf flaf

<toolkit:DataGrid x:Name="MyGrid" AutoGenerateColumns="False" 
    ItemsSource="{Binding MyCollection, Mode=Default}" 
    EnableColumnVirtualization="True" IsReadOnly="True" 
    ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}">  
    <toolkit:DataGrid.Columns>  
        <toolkit:DataGridTextColumn Binding="{Binding Path=MyEntry}" 
            Header="MyEntry" Visibility="{Binding IsChecked, Converter=
                {StaticResource booleanToVisibilityConverter}.... />
    </toolkit:DataGrid.Columns>     
</toolkit:DataGrid>  
Run Code Online (Sandbox Code Playgroud)

如果我不清楚请告诉我,我会尝试详细说明.

干杯,

Tim*_*ine 19

我刚刚写了一篇关于这个主题的博客文章.它允许通过右键单击任何列标题可访问的ContextMenu显示或隐藏DataGridColumns.此任务完全通过附加属性完成,因此它符合MVVM.

查看博文

  • SO规则建议链接到博客而不是发布显式内容并不理想.你真的可以在这里回答Q吗? (2认同)

Web*_*per 13

我一直在寻找一个通用的,XAML(即没有代码隐藏),自动和简单的列选择器上下文菜单示例,它绑定到WPF DataGrid列标题.我看过成百上千的文章,但他们都不做的正是正确的事情,或者他们没有通用不够.所以这就是我认为最好的组合解决方案:

首先,将它们放在资源字典中.我将把它作为练习留给读者编写可见性/布尔转换器,以确保复选框检查列何时可见,反之亦然.请注意,通过为上下文菜单资源定义x:Shared ="False",它将获得特定于实例的状态,这意味着您可以将此单个模板/资源用于所有数据网格,并且它们都将保持自己的状态.

<Converters:VisiblityToInverseBooleanConverter x:Key="VisiblityToInverseBooleanConverter"/>

<ContextMenu x:Key="ColumnChooserMenu" x:Shared="False"
             DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}" 
             ItemsSource="{Binding Columns, RelativeSource={RelativeSource AncestorType={x:Type sdk:DataGrid}}}">
    <ContextMenu.ItemContainerStyle>
        <Style TargetType="MenuItem">
            <Setter Property="Header" Value="{Binding Header}"/>
            <Setter Property="AutomationProperties.Name" Value="{Binding Header}"/>
            <Setter Property="IsCheckable" Value="True" />
            <Setter Property="IsChecked" Value="{Binding Visibility, Mode=TwoWay, Converter={StaticResource VisiblityToInverseBooleanConverter}}" />
        </Style>
    </ContextMenu.ItemContainerStyle>
</ContextMenu>

<Style x:Key="ColumnHeaderStyle" TargetType="{x:Type Primitives:DataGridColumnHeader}">
    <Setter Property="ContextMenu" Value="{StaticResource ColumnChooserMenu}" />
</Style>

<ContextMenu x:Key="GridItemsContextMenu" >
    <MenuItem Header="Launch Do Some other action"/>
</ContextMenu>
Run Code Online (Sandbox Code Playgroud)

然后按如下方式定义DataGrid(其中OrdersQuery是View-model公开的一些数据源):

<sdk:DataGrid ItemsSource="{Binding OrdersQuery}"
              AutoGenerateColumns="True" 
              ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}"
              ContextMenu="{StaticResource GridItemsContextMenu}">

  <!-- rest of datagrid stuff goes here -->

</sdk:DataGrid>
Run Code Online (Sandbox Code Playgroud)

这将为您提供以下内容:

  1. 绑定到列标题的上下文菜单,用作列选择器.
  2. 绑定到网格中项目的上下文菜单(对项目本身执行操作 - 再次,操作的绑定是读者的练习).

希望这能帮助那些一直在寻找这样一个例子的人.

  • 这个答案应该更高.简单,优雅的解决方案 (2认同)

小智 6

我知道这有点老了.但我正在考虑这样做,这篇文章更简单:http: //iimaginec.wordpress.com/2011/07/25/binding-wpf-toolkit%E2%80%99s-datagridcolumn-to-a-viewmodel- DataContext的-传播史换数据网格柱最MVVM路到互动与-的DataGridColumn /

您需要做的就是在列上设置DataContext,然后按照正常情况将Visibility绑定到ViewModel!:)简单有效