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
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
AKoran
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.
Fredrik Hedblad
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.
Fredrik Hedblad
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}}" />
AKoran
I'll give you credit since you got me thinking, but in the end there seems to be a much easier solution.
Daniel Albuschat
Then please share this easier solution with us, AKoran ;)