让用户选择要在WPF DataGrid上显示的列

时间:2011-01-12 01:05:10

标签: c# wpf wpf-controls wpfdatagrid

我的DataGrid有一组默认列显示,但我也想让用户选择/取消选择其应用程序中显示的列。在WPF中有相对简单的方法吗?

DataGrid绑定到DataTable

注意:如果上述功能过于复杂,我可以通过RadioButton解决方案使用简单的“默认列/所有列”。

3 个答案:

答案 0 :(得分:6)

简短的回答是,将每列的Visibility属性绑定到您能够设置的布尔标志(通过CheckBox或其他机制),并使用BooleanToVisibilityConverter来制作标志未设置时,列可见性折叠

挖掘此similar question,特别是this answer!他的博客文章列出了我理想的解决方案。 :)

答案 1 :(得分:6)

DataGrid.Columns绑定到ItemsControlDataTemplate包含CheckBox,其中包含VisbilityToBoolConverter可见性切换,除了<Window ... DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}" Loaded="Window_Loaded"> <Window.Resources> <local:VisibilityToBoolConverter x:Key="VisibilityToBoolConv"/> </Window.Resources> <StackPanel Orientation="Vertical"> <DataGrid ItemsSource="{Binding Data}" Name="DGrid"/> <ItemsControl ItemsSource="{Binding ElementName=DGrid, Path=Columns}" Grid.IsSharedSizeScope="True" Margin="5"> <ItemsControl.ItemTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="A"/> <ColumnDefinition SharedSizeGroup="B"/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding Header}" Margin="5"/> <CheckBox Grid.Column="1" IsChecked="{Binding Visibility, Converter={StaticResource VisibilityToBoolConv}}" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> </Window> 之外无需代码:< / p>

TextBlock

注意:我有一个[ValueConversion(typeof(Visibility), typeof(bool))] public class VisibilityToBoolConverter : IValueConverter { #region IValueConverter Members public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { Visibility vis = (Visibility)value; switch (vis) { case Visibility.Collapsed: return false; case Visibility.Hidden: return false; case Visibility.Visible: return true; } return false; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if ((bool)value) return Visibility.Visible; else return Visibility.Collapsed; } #endregion } ,假设Column-Header是一个字符串,如果不是这样的话可能需要调整。


VisibilityConverter:

{{1}}

答案 2 :(得分:1)

我更喜欢扩展DataGrid类并添加此功能。

public class DataGridEx : DataGrid
{
    public DataGridEx() : base()
    {
        // Create event for right click on headers
        var style = new Style { TargetType = typeof(DataGridColumnHeader) };
        var eventSetter = new EventSetter(MouseRightButtonDownEvent, new MouseButtonEventHandler(HeaderClick));
        style.Setters.Add(eventSetter);
        ColumnHeaderStyle = style;
    }

    private void HeaderClick(object sender, MouseButtonEventArgs e)
    {
        ContextMenu menu = new ContextMenu();
        // Fill context menu with column names and checkboxes
        var visibleColumns = this.Columns.Where(c => c.Visibility == Visibility.Visible).Count();
        foreach (var column in this.Columns)
        {
            var menuItem = new MenuItem
            {
                Header = column.Header.ToString(),
                IsChecked = column.Visibility == Visibility.Visible,
                IsCheckable = true,
                // Don't allow user to hide all columns
                IsEnabled = visibleColumns > 1 || column.Visibility != Visibility.Visible
            };
            // Bind events
            menuItem.Checked += (object a, RoutedEventArgs ea)
                => column.Visibility = Visibility.Visible;
            menuItem.Unchecked += (object b, RoutedEventArgs eb)
                => column.Visibility = Visibility.Collapsed;
            menu.Items.Add(menuItem);
        }
        // Open it
        menu.IsOpen = true;
    }
}

现在您可以使用此控件代替原始的DataGrid

<dg:DataGridEx ItemsSource="{Binding OfflineData, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False">
    <dg:DataGridEx.Columns>
        <DataGridTextColumn Binding="{Binding PortID}" Header="ID" Width="50" Visibility="Collapsed"/>
        <DataGridTextColumn Binding="{Binding SwitchIP}" Header="Switch IP" Width="100" Visibility="Visible"/>
        <DataGridTextColumn Binding="{Binding Port}" Header="Port" Width="50" Visibility="Visible"/>
    </dg:DataGridEx.Columns>
</dg:DataGridEx>

现在,用户可以右键单击列标题以打开带有复选框的菜单:

Now user can right-click on column header to open menu with checkboxes