I have a Grid to which the Visibility property is bound to IsExpanded of a parent Expander control.

Whenever Grid.Visibility changes, I want a property (MyProperty) on the DataContext (the view model) to change accordingly.

This is my XAML:

<Grid Visibility="{Binding IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Expander}}, Converter={StaticResource BoolToVisibilityConverter}}" />

I have tried programmatically setting the binding in the view constructor using:

grid.SetBinding(VisibilityProperty, new Binding("MyProperty") { Source = DataContext });

However, this just replaces the binding to the Expander already set in the XAML.

I considered flipping this around so that the target is my view model and the source is the grid instead (binding to Visibility) and making MyProperty into a dependency property. But, my view model is not a DependencyObject, so I cannot do this.

I have tried using a MultiBinding / MultiConverter binding Grid.Visibility to Expander.IsExpanded and MyProperty, but this doesn't have the desired effect. MyProperty doesn't get changed to Grid.Visibility when Grid.Visibility is updated as a result of Expander.IsExpanded changing.

The only option that seems to work is using an attached property on Grid which binds to Expander.IsExpanded and then use a callback function to programmatically change Grid.Visibility whenever the attached property changes. Grid.Visibility then binds to MyProperty. This just seems like a messy way of doing it, but I am open to suggestions.

I guess what I'm trying to do is almost like a two-pronged binding where the two bindings are in opposite directions, one being from a dependency property, the other being to a CLR property.

Thanks for any help that can be given!!

1

There are 1 best solutions below

1
On

I think you can set visibility of grid with triggers on Expanders and bind grid.Visibility to your ViewModel. This approach is similar to your solution with code behind but with triggers instead of code.

In my opinion your solution with code behind is good enough too. Who said that everything has to be in XAML not code-behind. Code-behind is usually bad for business logic and such but it is completely Ok to have visual logic in code-behind if it can't be expressed in XAML only.