WPF绑定:!值

21
我有一个按钮:
<Button Content="Stop loading" />

在ViewModel中我有一个名为IsLoaded的属性。我不想写一个名为IsNotLoaded的属性,但我想在绑定中使用IsLoaded并在IsLoaded = true时禁用按钮。

如何实现这样的功能:

<Button Content="Stop loading" IsEnabled="{Binding !IsLoaded}" />

附言:如果这比编写额外属性更困难,我将使用IsNotLoaded属性。


2
请参考这个 Stack Overflow 问题 - Nekresh
4个回答

27

标准的做法是创建一个IValueConverter,将会翻转您的布尔值。虽然创建此类比添加新属性更困难,但它是完全可重用的 - 因此,稍后,您可以在其他绑定中重复使用此类(而不会在 ViewModel 中污染大量的 !Property 属性)。

这个类看起来会像这样:

[ValueConversion(typeof(bool), typeof(bool))]
public class InvertBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool booleanValue = (bool)value;
        return !booleanValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool booleanValue = (bool)value;
        return !booleanValue;
    }
}

然后,您将其添加到您的资源中:

<src:InvertBoolConverter x:Key="invertBoolConverter"/>

一旦你拥有了这个,你可以像这样使用它:

<Button Content="Stop loading" 
        IsEnabled="{Binding IsLoaded, Converter={StaticResource invertBoolConverter}}" 
/>

1
你会认为微软会提供其中之一。他们已经提供了BooleanToVisibilityConverter。为什么不再提供一些其他有用的呢? - NielW

12
虽然转换器的答案都是有效的,但您可能希望查看另一种方法:指令。在WPF(以及在某种程度上Silverlight)中,您可以将ICommand绑定到该按钮。因此,如果您在ViewModel上创建了一个名为CancelLoadingCommand的属性,并实现了ICommand,那么您将按如下方式绑定该按钮:
<Button Content="Stop Loading" Command="{Binding CancelLoadingCommand}" />

在你的ViewModel中,CancelLoadingCommand的实现将类似于:

    public ICommand CancelLoadingCommand
    {
        get
        {
            if (_cancelLoadingCommand== null)
            {
                this._cancelLoadingCommand= new RelayCommand(
                    delegate
                    {
                        // Cancel the loading process.
                    },
                    delegate
                    {
                        return !this.IsLoaded;
                    }
                );
            }

            return _cancelLoadingCommand;
        }
    }
注意,这里我使用了一个RelayCommand(它是PRISM或MVVM-Light框架的一部分)。我建议你也去研究一下这两个框架。
希望这可以帮到你。

7

一种解决方案是使用转换器来反转布尔值。类似于:

public class InvertedBoolenConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return !(bool)value;

    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return !(bool)value;
    }
}

将转换器添加到某个资源中,然后在绑定中使用它:

<YourUserControl.Resources>
   <c:InvertedBoolenConverter x:Key="InvertedBoolenConverter" />
</YourUserControl.Resources>

<Button Content="Stop loading" IsEnabled="{Binding IsLoaded,Converter={StaticResource InvertedBoolenConverter}}" />

6

您想使用转换器。这里有一个可以为您完成任务的转换器。

  public class booleaninverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
      return !(bool)value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
      return !(bool)value;
    }
  }

要使用它,需按如下方式编写您的xaml代码。
<Button Content="Stop loading" IsEnabled="{Binding IsLoaded, Converter={StaticResource booleaninverter}" />

你可以将静态资源放在App.xaml中,或其他窗口/控件资源部分。当然,你需要进行“本地”命名空间声明等操作,但这为你完成了大部分工作。
<local:booleaninverter x:key="booleaninverter"/>

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