Property Foo
is in my DataContext
ViewModel {
Visibility Foo;
}
But I cannot figure out how to access Foo
inside a Column
. In this case, I assume it's probably looking for Foo
in whatever object is bound to the DataGrid
ItemsSource
<DataGrid Visibility="{Binding Foo}"> // works
<DataGrid.Columns>
<DataGridTextColumn Visibility="{Binding Foo}" /> // fails
I have tried
Binding="{Binding DataContext.Foo}"
And a bunch of things with RelativeSource
tags as well.
Also, is there some way to view and select a property to bind to from a GUI?
Edit: It turns out that the Columns themselves are not FrameworkElements, so they cannot locate the DataGrid ancestor. You can however use the technique in the answer below to bind properties of the CellTemplate of the Column to the DataContext.
This should work:
<DataGridTextColumn Visibility="{Binding Path=DataContext.Foo, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
You're right about the column being bound to the current item - that's why you need to use RelativeSource
to get the DataGrid, and then access the Foo
property in its DataContext
.
As for selecting the property to bind to, there's the WPF designer's properties panel and visual studio addons such as Resharper which can help, but eventually they don't do such a great job at anything other than simple bindings, so what you're left with is yourself and your understanding of what's going on.
I found a few approaches to binding outside of the visual tree from this article: Artificial Inheritance Contexts in WPF
I am using yet a fourth option (related to what he suggests). It is fairly hacky but simple. It has the downside that the WPF designer does not like it and puts errors in your error log during design time. In order to get to the ambient DataContext
, you can bind to something else in the current XAML file that IS in the visual tree, using the x:Reference
markup extension (see msdn). This is similar to binding by ElementName
except that it is not dependent on having an InheritanceContext
, which you typically don't outside of the visual tree. I just use a dummy FrameWorkElement
if there is nothing else in the UserControl
to reference.
I tried to just reference the containing UserControl
(or Window
or Page
, etc) but this leads to a circular reference exception, so I live with the dummy element until someone shows me a better way.
<FrameworkElement Name="dummyElement" />
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn
Visibility="{Binding Source={x:Reference dummyElement},
Path=DataContext.Foo}"
/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With