2

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 Answers 2

8

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}"/>
Sign up to request clarification or add additional context in comments.

Comments

3

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

5 Comments

That works for the entire column...what I'm looking for is individual row control. For example, row 1 has 5 columns and row 2 has 4 columns because one of them is hidden.
Updated my example, hopefully this will do it :) Added DataContext="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=SelectedItem}" for the DataGrid and a Converter for each column.
Or maybe a better way to do it without the converter if you're binding against a Visibility Property. <DataGridTextColumn Binding="{Binding Value}" Visibility="{Binding Path=(FrameworkElement.DataContext).ColumnAVisibility, RelativeSource={x:Static RelativeSource.Self}}" />
I'll give you credit since you got me thinking, but in the end there seems to be a much easier solution.
Then please share this easier solution with us, AKoran ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.