WPF DataGrid - скрытие столбца с помощью CheckBox - PullRequest
7 голосов
/ 09 июля 2010

Я пытаюсь контролировать видимость столбца с помощью флажка (это в WPF 4.0).

Вот фрагмент моего XAML:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
</Window.Resources>

<CheckBox x:Name="GeneralDetailsVisible" Content="General Details"  Margin="5"/>

<DataGridTextColumn Header="Crew" 
  Binding="{Binding Path=Crew}" 
  Visibility="{Binding ElementName=GeneralDetailsVisible, 
                       Converter={StaticResource BoolToVisConverter}, 
                       Path=IsChecked}">
</DataGridTextColumn>

Теперь я знаюконвертер BooleanToVisibilityConverter работает, так как я привязал его к текстовому блоку, и я вижу ожидаемые значения.Если я ввожу значения вручную в свойство видимости столбцов, это работает.Но не тогда, когда я связываю это.Что я делаю не так?

Ответ:

Квартмейстер указал мне на ответ.Страница, на которую он указал, немного вводит в заблуждение, так как код, указанный в сообщении, не работает, и вы должны посмотреть пример кода.

Вот мой последний рабочий код для всех, кто сталкивается с этой проблемой:

Конвертер для преобразования нашего свойства bool ViewModels в правильное значение Visibility для нашего атрибута столбца.

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
</Window.Resources>

Привязать флажок к свойству ViewModels, которое будет контролировать видимость столбцов.

<CheckBox
  x:Name="DetailsVisible" 
  Content="Show Details"
  IsChecked="{Binding Path=DisplayDetails}" />

Затем привяжите видимость к свойству ViewModels DisplayDetails.Обратите внимание, что это собственный столбец DataContext, к которому привязан.

<DataGridTextColumn
  Header="Reliability" 
  Binding="{Binding Path=Reliability}" 
  Visibility="{Binding (FrameworkElement.DataContext).DisplayDetails, 
                       RelativeSource={x:Static RelativeSource.Self}, 
                       Converter={StaticResource BoolToVisConverter}}">
</DataGridTextColumn>

Добавьте следующий код в ваш проект, это позволит отловить изменение в DataGrids DataContext.

FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));

FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid),
        new FrameworkPropertyMetadata
           (null, FrameworkPropertyMetadataOptions.Inherits,
           new PropertyChangedCallback(OnDataContextChanged))); 

Затем, когда изменяется ваш DataGrids DataContext, мы обновляем все прикрепленныеDataGridColumsn с новым DataContext.

public static void OnDataContextChanged(DependencyObject d,
                                        DependencyPropertyChangedEventArgs e)
{
    DataGrid grid = d as DataGrid;
    if (grid != null)
    {
        foreach (DataGridColumn col in grid.Columns)
        {
            col.SetValue(FrameworkElement.DataContextProperty, e.NewValue);
        }
    }
}

Один Gotcha для поиска.Если вы добавите свой DataContext на свою страницу следующим образом:

<Window.DataContext>
    <vm:WeaponListViewModel />
</Window.DataContext>

Тогда вышеупомянутая функция будет вызываться до того, как в вашей DataGrid появятся какие-либо столбцы!код после создания окна.

Ответы [ 2 ]

3 голосов
/ 09 июля 2010

Проблема в том, что столбцы DataGrid не являются частью визуального дерева, поэтому они не могут использовать привязки.(Свойство «Binding» на самом деле является обычным свойством типа Binding, а не свойством зависимости. Оно применяет этот объект привязки к ячейкам, которые являются частью визуального дерева.)

Вот ссылка наблог, который имеет обходной путь и демонстрирует привязку видимости столбца к флажку: http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx

2 голосов
/ 07 августа 2013

IMO с использованием x:Name, x:Reference и Source проще:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>

<CheckBox x:Name="showImperial" Content="Show Details" />

<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="TOV (Bls)" 
                    Width="80" 
                    Binding="{Binding TOVBarrels}"
                    Visibility="{Binding Source={x:Reference showImperial},
                                 Path=IsChecked, 
                                 Converter={StaticResource BooleanToVisibilityConverter}}"/>
</DataGrid.Columns>
</DataGrid>

См. Этот ответ: Привязка видимости к проверяемому пункту меню показывает ошибку «Поставщик услуг отсутствует INameResolverуслуга "в WPF

...