Xamarin Forms - 否定布尔绑定值

Posted

技术标签:

【中文标题】Xamarin Forms - 否定布尔绑定值【英文标题】:Xamarin Forms - negate bool binding values 【发布时间】: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 创建新变量?

【问题讨论】:

【参考方案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>

【讨论】:

邪恶的。非常感谢

以上是关于Xamarin Forms - 否定布尔绑定值的主要内容,如果未能解决你的问题,请参考以下文章

将方法从后面的代码转换为 ICommand 数据绑定 Xamarin.Forms

自定义控件的 Xamarin 数据绑定值计算为 Xamarin.Forms.Binding

Xamarin.Forms绑定初始值后不更新

Xamarin Forms Android:获取 XA3001:无法 AOT 程序集

将绑定值设置为 Xamarin Forms 中行为的参数

Xamarin Forms 两种方式绑定ActivityIndi​​cator