4

I have two Menu Item elements - "Undelete" and "Delete" who have complementary visibility: when one is shown, the other one is hidden.

In the code of the ViewModel I have a dependency property FilesSelectedCanBeUndeleted defined as below:

private bool _filesSelectedCanBeUndeleted;
public bool FilesSelectedCanBeUndeleted
{
    get
    {
        return _filesSelectedCanBeUndeleted;
    }
    set
    {
        _filesSelectedCanBeUndeleted = value;
        OnPropertyChanged("FilesSelectedCanBeUndeleted");
    }
}

the XAML for the Undelete button looks like below:

<MenuItem Header="Undelete" Command="{Binding UndeleteCommand }" 
Visibility="{Binding Path=FilesSelectedCanBeUndeleted, 
Converter={StaticResource BoolToVisConverter}}" >

As you can see the Visibility of the Undelete is bind to the FilesSelectedCanBeUndeleted property ( with the help of a BooleanToVisibilityConveter).

Now my question is, how can I write the XAML to bind the Visibility of the Delete button to the "NOT" value of the FilesSelectedCanBeUndeleted property?

Thanks,

sean717
  • 11,759
  • 20
  • 66
  • 90

4 Answers4

5

Here is an example of a custom IValueConverter, that allows you to reverse the visibility logic. Basically, one MenuItem will be visible when your view-model property is true, and the other would be collapsed.

So you'd need to define two instances of the converter like so:

<local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<local:BooleanToVisibilityConverter x:Key="ReversedBooleanToVisibilityConverter" IsReversed="true" />
CodeNaked
  • 40,753
  • 6
  • 122
  • 148
3

You can use apply the datatrigger to you menuitem to avoid another property in your viemodel like this -

        <MenuItem Header="Delete"
                  Command="{Binding DeleteCommand }">
            <MenuItem.Style>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter Property="Visibility" Value="Visible" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding FilesSelectedCanBeUndeleted}" Value="False">
                            <Setter Property="Visibility"
                                    Value="Collapsed" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </MenuItem.Style>
        </MenuItem>
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
1

Create new property on your ViewModel and just Negate 'FilesSelectedCanBeUndeleted' and then bind to it.

ozczecho
  • 8,649
  • 8
  • 36
  • 42
  • Yes, that's what I am doing now. It works but I hope I can get around without creating a somewhat redundant property. Thanks. – sean717 Apr 18 '11 at 23:41
0

I did something like this a while ago with a simple negation...

    private bool _filesSelectedCanBeUndeleted;
public bool FilesSelectedCanBeUndeleted{    
        get{ 
            return _filesSelectedCanBeUndeleted;    
            }   
        set{        
            _filesSelectedCanBeUndeleted = value;        
            OnPropertyChanged("FilesSelectedCanBeUndeleted");    
            // You have also to notify that the second Prop will change
            OnPropertyChanged("FilesSelectedCanBeDeleted");    
            }}

public bool FilesSelectedCanBeDeleted{
        get{
            return !FilesSelectedCanBeUndeleted;
        }
        }

Xaml could look like this then ....

<MenuItem Header="Delete" 
    Command="{Binding DeleteCommand }" 
    Visibility="{Binding Path=FilesSelectedCanBeDeleted, Converter={StaticResource BoolToVisConverter}}" >
silverfighter
  • 6,762
  • 10
  • 46
  • 73