wpfdatagridimultivalueconverter

I can't get the property of the view model in the multi value converter


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?


Solution

  • 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.