Monday, September 13, 2010

WPF DataGrid columns are not part of visual tree

Sometime we have a requirement where 2 columns out of total 4 had to be hidden based on the presenter logic.
As per the “usual” WPF knowledge I bound the Visibility property of Datagrid column property to presenter property which threw an exception “System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element”.
This led to suspicion that the column is not able to inherit Datagrid’s datacontext, we tried binding using relative source and find ancestor but nothing seemed to work. It is then that it clicked that Datagrid columns are not part of Datagrid visual tree.
So how do we achieve the desired behavior? There are 3 ways I have tried to solve it,
  1. Attached property behavior:
    Create a Dependency property; bind this dependency property with the presenter property. Override the property metadata of the dependency property with attaching a function to be called whenever the property’s source is changed. In this function we can do operation on the columns.
  2. Reverse the binding direction:
    Up until now we have considered presenter as source and view as target. But we can also make presenter as target and view as source, like to solve the above problem we can do binding at runtime for the datagrid columns with column’s Visibility as source and presenter’s property as target and two way binding.
  3. Forward the Datagrid’s datacontext to its columns:
    Using the WPF property system we can add Framework.DataContext property to DataGridColumn,and then override Datagrid’s DataContext metadata to listen for its changes. In the callback method we can then set the DataContext (one we got by adding before) of each column with the new DataContext.

2 comments: