I have a DataGrid
. I want to decide when to collapse a column and when to show it.
This is my code:
<UserControl.Resources>
<ResourceDictionary>
<FrameworkElement x:Key="ProxyElement" DataContext="{Binding}" />
</ResourceDictionary>
<UserControl.Resources>
<DataGridTextColumn.Visibility>
<MultiBinding Converter="{StaticResource MyMultiValueConverter}">
<Binding Source="{StaticResource ProxyElement}" Path="DataContext.MyPropertyInViewModel" />
<Binding Source="1"/>
</MultiBinding>
</DataGridTextColumn.Visibility>
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
//Do the conversion
}
I need the proxy element to access the view model from an element that doesn't belong to the visual tree.
In the MultiBinding
, the second binding works. In the converter I receive the value 1
, but the problem is with the first element. I don't get the property of the view model, that it is a string
. I get a DependencyProperty.UnsetValue
.
How can I pass a property of my view model to the multi-value converter?
The ProxyElement
will not bind the data context in Resources
as it is not part of the visual tree. To make this work, define the FrameworkElement
anywhere in the visual tree, e.g. like below in a Grid
. The DataContext
is inherited, but you can also set it explicitly. Set the Visibility
of the proxy to Collapsed
, so it is hidden.
<Grid>
<!-- ...grid definitions. -->
<FrameworkElement Grid.Row="42" x:Name="ProxyElement" Visibility="Collapsed"/>
</Grid>
Reference it using x:Reference
, since ElementName
bindings only work in the visual tree, but columns are not part of it.
<DataGridTextColumn.Visibility>
<MultiBinding Converter="{StaticResource MyMultiValueConverter}">
<Binding Source="{x:Reference ProxyElement}" Path="DataContext.InitialDepositAmount"/>
<Binding Source="1"/>
</MultiBinding>
</DataGridTextColumn.Visibility>
A better way is to use a Freezable
as binding proxy. Those can access the data context even outside of the visual tree. See this related post that shows an approach with a custom BindingProxy
, that also works in Resources
and without x:Reference
.