2
votes

Is there any way to hide a given column based on a binding. I've tried setting the visibility property on DataGridTextColumn (using the correct converter), but that doesn't seem to work. If I set the value directly (not through binding) it works. So is column visibility an all or nothing deal with the datagrid?

2

2 Answers

8
votes

All you really have to do is add:

    <Style x:Key="vStyle" TargetType="{x:Type DataGridCell}">
        <Setter Property="Visibility" Value="{Binding YourObjectVisibilityProperty}"/>
    </Style>

and then in use the following in your columns:

<DataGridTextColumn CellStyle="{StaticResource vStyle}"/>
3
votes

Take a look at this post, the problem is explained
Binding in a WPF data grid text column
and here
http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx

Quoting JaredPar from the first link
"Essentially the problem is that the DataGridTextColumn has no parent from which to inherit a Binding because it is not a part of the logical or visual tree. You must setup an inheritance context in order to get access to the binding information"

Workaround in order to get this to work..

public class DataGridContextHelper
{
    static DataGridContextHelper()
    {
        DependencyProperty dp = FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));
        FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid),
        new FrameworkPropertyMetadata
           (null, FrameworkPropertyMetadataOptions.Inherits,
           new PropertyChangedCallback(OnDataContextChanged)));
    }

    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);
            }
        }
    }
}

public partial class App : Application
{
    static DataGridContextHelper dc = new DataGridContextHelper(); 
}

<DataGrid x:Name="c_dataGrid" AutoGenerateColumns="False" DataContext="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=SelectedItem}">
    <DataGrid.Columns>
        <DataGridTextColumn Visibility="{Binding Path=(FrameworkElement.DataContext), RelativeSource={x:Static RelativeSource.Self}, Converter={StaticResource HideColumnAConverter}}" />
    </DataGrid.Columns>
</DataGrid>

object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    if (value == null)
    {
        return Visibility.Visible;
    }
    // Whatever you're binding against
    TestClass testClass = value as TestClass;
    return testClass.ColumnAVisibility;
}