【问题标题】:Xamarin Forms - negate bool binding valuesXamarin Forms - 否定布尔绑定值
【发布时间】:2018-03-01 03:30:24
【问题描述】:

我正在学习 xamarin 形式和 mvvm 模式。我想知道,是否可以否定绑定布尔值。我的意思是:

我有,假设是带有 isVisible 绑定的条目:

<Entry
    x:Name="TextEntry"
    IsVisible="{Binding IsVisibleEntry}"
/>

Label,当TextEntry 可见时我想隐藏它。

<Label x:Name="MainLabel" 
       isVisible="!{Binding IsVisibleEntry}"/> //ofc it is not working

是否可以不为 ViewModel 中的 MainLabel 创建新变量?

【问题讨论】:

    标签: c# xamarin mvvm xamarin.forms


    【解决方案1】:

    您需要创建一个 Invert 转换器,以便您的绑定看起来像这样:

    public class InverseBoolConverter : 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 中

    <local:InverseBoolConverter x:Key="inverter"/>
    <Entry
    x:Name="TextEntry"
    IsVisible="{Binding IsVisibleEntry, Converter={StaticResource inverter}}"
    />
    

    【讨论】:

    • 有几次我花了几个小时试图让它工作,但我从来没有。我总是得到Type core:InverseBoolConverter not found in xmlns Igs.Mobile.Core 或等同于我命名事物的方式。
    • 您确定 ConvertBack 会返回 !value 吗?因为接受的答案只是返回值。
    • @GautamJain - 接受的答案是错误的 - 它应该反转两个地方。但是,只有在值上使用“双向绑定”时才重要。否则,永远不会调用 ConvertBack。
    【解决方案2】:

    选项一:转换器

    定义转换器:

        public class InverseBoolConverter : 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 value;
                //throw new NotImplementedException();
            }
        }
    

    在 XAML 中的使用:

        <Label x:Name="MainLabel" 
               isVisible="{Binding IsVisibleEntry, Converter={Helpers:InverseBoolConverter}}"/>
    

    XAML 标头

        xmlns:Helpers="clr-namespace:HikePOS.Helpers"
    

    选项二:触发

        <Label x:Name="MainLabel" isVisible="{Binding IsVisibleEntry}">
            <Label.Triggers>
                <DataTrigger TargetType="Label" Binding="{Binding IsVisibleEntry}" Value="True">
                    <Setter Property="IsVisible" Value="False" />
                </DataTrigger>
            </Label.Triggers>
        </Label>
    

    【讨论】:

    • 哪个更可取?
    • 我会选择选项 1,它也适用于例如ListView 等将使您的代码更清洁和更精简
    • 这是一个旧答案,但 ConvertBack 的正文中也应该有 return !((bool)value);
    【解决方案3】:

    我喜欢已经提供的答案,但我想我会添加我自己有时一直在使用的版本。使用 MVVM 架构,View Model 的属性都在对象设置器中调用SetProperty(),这会引发INotifyPropertyChanged 事件。我一直在做的是向视图模型添加第二个属性,并在第一个属性的设置器中将其值设置为!value

    例如,只要属性ViewModel.IsBusy = true 是这种情况,我就希望按钮为button.IsEnabled = false。这是一个反向布尔示例,就像您要询问的那样。

    ViewModel.cs 属性:

    public bool EnableButton
    {
        get { return enableButton; }
        set { SetProperty(ref enableButton, value); }
    }
    private bool isBusy;
    bool IsBusy
    {
        get { return isBusy; }
        set
        {
            SetProperty(ref isBusy, value);
            EnableButton = !value;
        }
    }
    

    XAML:

    <ActivityIndicator IsRunning="{Binding IsBusy}"/>
    
    <Button Text="Start Sync"
            Command="{Binding SyncCommand}"
            IsEnabled="{Binding EnableButton}"/>
    

    这样,在我调用IsBusy = true的代码中,它会同时设置button.IsEnabled = false,解决了反向布尔问题。

    【讨论】:

      【解决方案4】:

      您可以使用Xamarin Community Toolkit,而不是编写自己的转换器,它现在有一个可以开箱即用的转换器invertedboolconverter。这个例子(取自微软的文档)展示了它是如何工作的:

      <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                   xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
                   x:Class="MyLittleApp.MainPage">
      
          <ContentPage.Resources>
              <ResourceDictionary>
                  <xct:InvertedBoolConverter x:Key="InvertedBoolConverter" />
              </ResourceDictionary>
          </ContentPage.Resources>
      
          <StackLayout>
      
              <Label IsVisible="{Binding MyBooleanValue, Converter={StaticResource InvertedBoolConverter}}" />
      
          </StackLayout>
      </ContentPage>
      

      【讨论】:

      • 邪恶的。非常感谢
      猜你喜欢
      • 1970-01-01
      • 2011-01-27
      • 1970-01-01
      • 1970-01-01
      • 2019-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多