Jaime Rodriguez On Windows Phone, Windows Presentation Foundation, Silverlight and Windows 7
DataContext is a very handy inherited property on any WPF application.. Most of the time, I set DataContext near the root on the [logical] tree, and let the inherited DataContext do its magic to bind the rest of the scene. I recently tried to bind a DataGridColumn to its inherited DataContext (via its datagrid container) and got a very surprising answer on the output trace window:
“System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element…”
What is happening here? The Columns collection is just a property in the Datagrid; this collection is not in the logical (or visual) tree, therefore the DataContext is not being inherited, which leads to there being nothing to bind to.
I needed the functionality so I had to create a workaround.. With out much thought I decided to:
To get it done, I did not inherit from DataGrid and create a new class.. Instead i used the richness of WPF’s property system to pull a 1,2 punch:
Code looks like this:
The OnDataContextChanged callback simply forwards the DataContext from DataGrid to its columns:
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 ); } } }
That is it. Now we are ready to databind to DataGridColumns. <dg:DataGridTextColumn Binding="{BindingA}" Visibility="{Binding ElementName=ShowA,Path=IsChecked , Converter={StaticResource BoolToVisConverter}}" />
You can download source code for a small sample from here.
A few more thoughts on DataGridColumn not being in the tree ..
Happy datagrid coding.. Again, there is source here.
PingBack from http://mstechnews.info/2008/11/forwarding-the-datagrid%e2%80%99s-datacontext-to-its%e2%80%99-columns/
hey there,
Josh also did something similar for this...
http://blogs.infragistics.com/blogs/joshs/archive/2008/06/26/data-binding-the-isvisible-property-of-contextualtabgroup.aspx
have a look it is really cool....
Hey Marlon,
I am a fan of Josh's blog so I knew of the Freezable approach.. If I was to 'come up' with a few reasons I did not use it:
1) I mostly wanted people to know the Columns have no DataContext ... so I provided the smallest tightest solution keeping to show the problem and workaround..
2) Long-term simplicity.. I wanted to keep it all to code-behind and not touch the tree... this way when WPF team fixes the bug I can just blow away my static and be done.. not touching xaml or tree. Minimal surface (even if less flexibility).
When I first wrote the post, I even wrote the line that said it could also be accomplished via Freezable.. not sure why I deleted and replaced it for a "with out much thought" prefix to the solution.. I blame mid-night blogging for that ;)
Since the release of the WPF DataGrid there have been several common patterns of questions that developers