Xamarin Forms - 否定bool绑定值

时间:2017-09-20 07:29:44

标签: c# xamarin mvvm xamarin.forms

我正在学习xamarin表格和mvvm模式。我想知道,是否有可能否定绑定bool值。我的意思是:

我有,让我们说使用isVisible Binding进入:

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

Label我想在TextEntry可见时隐藏。

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

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

4 个答案:

答案 0 :(得分:28)

选项一:转换器

public class InverseBoolConverter : IValueConverter, IMarkupExtension
    {
        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();
        }


        public object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }
    }

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 :(得分:5)

您需要创建一个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}}"
/>

答案 2 :(得分:1)

您可以使用 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>

答案 3 :(得分:0)

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

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

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,从而解决了反向布尔问题。