如何在XAML (WPF)中对Visibility属性进行简单的条件绑定

38

我有一个视图模型,其中包含一个属性:

public class MyModel
{
    public bool IsEnabled {get;set;}
}

我想使用这个属性来切换按钮的状态。如果布尔值为真,我想隐藏按钮,否则显示它。

我尝试过以下方法:

<Button Visibility= "{Binding IsEnabled ? Hidden : Visible  }">Enable</Button>

但这不合适。

我尝试了一些更复杂的解决方案,但我的猜测是我错过了一些微不足道的东西。

有什么建议吗?


3
你需要在可见性转换器中添加一个布尔值。 - Hafiz H
3个回答

55

因为您想在隐藏可见之间切换,而true表示隐藏,所以您可以编写自定义的IValueConverter或使用简单的Style.Trigger

<Button Content="Enable">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Visibility" Value="Visible"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsEnabled}" Value="True">
                    <Setter Property="Visibility" Value="Hidden"/>
                </DataTrigger>
            </Style.Triggers>                    
        </Style>
    </Button.Style>
</Button>

假设DataContext已根据要求设置并且MyModel.IsEnabled在每次更改时都会引发INotifyPropertyChanged.PropertyChanged事件。

public class MyModel : INotifyPropertyChanged
{
    private bool _isEnabled;

    public bool IsEnabled
    {
        get { return _isEnabled; }
        set
        {
            _isEnabled = value;
            OnPropertyChanged("IsEnabled");
        }
    }

    #region INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

3
非常好,我从你的回答中学到了很多。<DataTrigger> 是一种通用(最佳实践)方法,用于使用此类特定逻辑修改 XAML 元素的属性吗? - Stefan
1
这要看情况。有时源和目标之间的关系更加复杂,需要编写 IValueConverterIMultiValueConverter,但如果你只有一个值,从整个源属性值范围中选出某些值时应该发生某些事情 - 在您的情况下为 true 时隐藏 - 使用 DataTrigger 更容易。 - dkozl

27

使用BooleanToVisibilityConverter:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>

<Button Visibility= "{Binding IsEnabled, Converter={StaticResource BooleanToVisibilityConverter}}" />

4
这有所不同,因为BooleanToVisibilityConverter将false值返回Collapsed(而不是Hidden)。OP还切换了布尔值,因此true应映射到Hidden,false应映射到Visible。 - Mike Zboray
1
除了 true 会表示可见而不是隐藏/折叠。 - dkozl
1
而且op还需要实现INotifyPropertyChanged :) - Krishna
我点赞了这个答案,因为这正是我所需要的。 - Tony_KiloPapaMikeGolf

4
添加一个继承自IValueConverter的类。
public class BooleanToVisibilityConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool bValue = (bool)value;
        if (bValue)
            return Visibility.Visible;
        else
            return Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Visibility visibility = (Visibility)value;

        if (visibility == Visibility.Visible)
            return true;
        else
            return false;
    }
    #endregion
}

2
现在,System.Windows.Controls 中已经内置了 [BooleanToVisibilityConverter 类],可以实现此功能。 - GrahamS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接