我拥有的是一个具有IsReadOnly属性的对象。如果此属性为true,我想将按钮上的IsEnabled属性设置为false(例如)。

我愿意相信我可以像IsEnabled="{绑定路径=!IsReadOnly}”,但这与WPF不兼容。

我是否不得不经历所有的样式设置?对于将一个bool值设置为另一个bool值的倒数这样简单的事情来说,似乎太啰嗦了。

<Button.Style>
    <Style TargetType="{x:Type Button}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="True">
                <Setter Property="IsEnabled" Value="False" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="False">
                <Setter Property="IsEnabled" Value="True" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Button.Style>

当前回答

我希望我的XAML尽可能保持优雅,所以我创建了一个类来包装驻留在我的一个共享库中的bool类型,隐式操作符允许类在代码中无缝地用作bool类型

public class InvertableBool
{
    private bool value = false;

    public bool Value { get { return value; } }
    public bool Invert { get { return !value; } }

    public InvertableBool(bool b)
    {
        value = b;
    }

    public static implicit operator InvertableBool(bool b)
    {
        return new InvertableBool(b);
    }

    public static implicit operator bool(InvertableBool b)
    {
        return b.value;
    }

}

你的项目需要做的唯一改变就是让你想要反转的属性返回this而不是bool

    public InvertableBool IsActive 
    { 
        get 
        { 
            return true; 
        } 
    }

在XAML中,用Value或Invert后缀绑定

IsEnabled="{Binding IsActive.Value}"

IsEnabled="{Binding IsActive.Invert}"

其他回答

我建议使用https://github.com/JohannesMoersch/QuickConverter

反转一个布尔值就像这样简单: <Button IsEnabled="{qc:正在绑定'!$P', P={正在绑定IsReadOnly}}" />

这加快了编写转换器通常所需的时间。

类似于jevansio的回答,实现了一个名为BindableBool的类,具有isstrue和IsFalse属性,我可以将两个替代组件的IsVisible绑定到。

Github: https://github.com/balintn22/BindableBool

努格特:是的。可绑定布尔

I did something very similar. I created my property behind the scenes that enabled the selection of a combobox ONLY if it had finished searching for data. When my window first appears, it launches an async loaded command but I do not want the user to click on the combobox while it is still loading data (would be empty, then would be populated). So by default the property is false so I return the inverse in the getter. Then when I'm searching I set the property to true and back to false when complete.

private bool _isSearching;
public bool IsSearching
{
    get { return !_isSearching; }
    set
    {
        if(_isSearching != value)
        {
            _isSearching = value;
            OnPropertyChanged("IsSearching");
        }
    }
}

public CityViewModel()
{
    LoadedCommand = new DelegateCommandAsync(LoadCity, LoadCanExecute);
}

private async Task LoadCity(object pArg)
{
    IsSearching = true;

    //**Do your searching task here**

    IsSearching = false;
}

private bool LoadCanExecute(object pArg)
{
    return IsSearching;
}

然后,对于组合框,我可以直接绑定到IsSearching:

<ComboBox ItemsSource="{Binding Cities}" IsEnabled="{Binding IsSearching}" DisplayMemberPath="City" />

在视图模型中再添加一个属性,它将返回反向值。 然后把它绑定到按钮上。 像;

视图模型:

public bool IsNotReadOnly{get{return !IsReadOnly;}}

在xaml:

IsEnabled="{Binding IsNotReadOnly"}

在@Paul的回答之后,我在ViewModel中写了以下内容:

public bool ShowAtView { get; set; }
public bool InvShowAtView { get { return !ShowAtView; } }

我希望在这里有一个片段可以帮助到一些人,可能是像我这样的新手。 如果有错误,请告诉我!

顺便说一句,我也同意@heltonbiker的评论——如果你不用使用它超过3次,这绝对是正确的方法……