0
        <Grid x:Name="RedGrid" Visibility="{Binding Path=IsVisible,
        Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">

As you can see the Visibility of this Grid is tied to the IsVisible property.

        <DataTemplate.Triggers>
            <Trigger SourceName="RedGrid" Property="Opacity" Value="0">
                <Setter TargetName="RedGrid" Property="Visibility" Value="Collapsed"/>     
            </Trigger>
        </DataTemplate.Triggers>

This part of code will change the visibility of the RedGrid once the opacity reachs / equals zero

But obviously the second part of the code doesn't work, since the Setter for IsVisible is not called when the Visibility of RedGrid is successfully changed to Collapsed.

    public Visibility IsVisible
    {
        get => _isVisible;

        set
        {
           _isVisible = value;
           RaisePropertyChanged("IsVisible");
        }
    }
  • This `IsVisible` property, is it of type `bool` or `Visibility` ? And can you provide a sample code of the `ViewModel` or the `DataContext`. – Ahmed Zaki Jul 26 '21 at 19:23
  • @AhmedZaki thanks for taking your time commenting. I added the IsVisible property to the question – maxmustermann Jul 27 '21 at 08:06

1 Answers1

0

What you are trying to do is to update the Visibility property of the Grid using a Setter and maintain the binding at the same time. The problem is that binding is overwritten by the Setter!

When you use Xaml Setters you set properties the same way as you set them in the tag, so when you write:

<Setter TargetName="RedGrid" Property="Visibility" Value="Collapsed"/>

It acts the same way as if you've written:

<Grid x:Name="RedGrid" Visibility="Collapsed">

Notice that the binding Visibility="{Binding Path=IsVisible"} has been overwritten by the value Visibility="Collapsed" and will no longer work.


But Why?

The way that TwoWay binding works can be found inside the controls themselves. When you work with DependencyProperties by default you set them using SetValue() method, which sets the property's value and overwrites any binding in place.

However, in controls like TextBox or CheckBox that take in user input, when the user interacts with them, properties like TextBox.Text and CheckBox.IsChecked are being set by the method SetCurrentValue() which like the documentation says:

The SetCurrentValue method changes the effective value of the property, but existing triggers, data bindings, and styles will continue to work.

You can review this question for more information about the differences between SetValue() and SetCurrentVaule() methods.


What to do:

In your case, I think that you can add a GridOpacity property to the view model, and instead of changing the Visibility in Xaml using a Setter, you can change the view model's IsVisible property directly when you set the GridOpacity property.

Here is a sample code of the view model:

private Visibility _isVisible;
public Visibility IsVisible
{
    get => _isVisible;
    set
    {
        if (_isVisible == value)
        {
            return;
        }
        _isVisible = value;
        RaisePropertyChanged(nameof(IsVisible));
    }
}

private double _gridOpacity;
public double GridOpacity
{
    get => _gridOpacity;
    set
    {
        if (_gridOpacity == value)
        {
            return;
        }
        _gridOpacity = value;
        RaisePropertyChanged(nameof(GridOpacity));

        // Change the visibility of the grid when opacity hits 0.
        if (value == 0)
        {
            IsVisible = Visibility.Collapsed;
        }
        else
        {
            // Change it back.
            IsVisible = Visibility.Visible;
        }
    }
}

And here is the Xaml:

<Grid x:Name="RedGrid" Visibility="{Binding IsVisible}" Opacity="{Binding GridOpacity}">
    ...
</Grid>

Ahmed Zaki
  • 104
  • 3
  • 11