Xamarin Forms -否定bool绑定值

gev0vcfq  于 2023-08-01  发布在  其他
关注(0)|答案(5)|浏览(105)

我正在学习xamarin表单和mvvm模式。我想知道,是否有可能否定绑定布尔值。我的意思是:
我有,让我们说使用isVisible绑定的Entry:

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

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

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


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

shyt4zoc

shyt4zoc1#

方案一:转换器

定义转换器:

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 Header

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>

t9eec4r0

t9eec4r02#

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

字符串

8qgya5xd

8qgya5xd3#

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

bwleehnv

bwleehnv4#

尽管@praty的解决方案有效,但如果你像我一样使用自定义控件/视图或XCT的弹出窗口。在XAML中使用转换器之前,我们需要像这样指定:

<ContentView.Resources>
    <converters:InverseBoolConverter x:Key="invrerseBoolConverter" />
</ContentView.Resources>

字符串
因此,最终代码将是:

InverseBoolConverter.cs

// Under namespace MyProject.Converters

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代码

<xct:Popup ...
           xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
           xmlns:converters="clr-namespace:MyProject.Converters"
           ...>

    <ContentView>
        <ContentView.Resources>
            <converters:InverseBoolConverter x:Key="inverseBoolConverter" />
        </ContentView.Resources>

        <StackLayout>
            <Label IsVisible="{Binding IsVisibleLabel, Converter={StaticResource inverseBoolConverter}}" />
        </StackLayout>
    </ContentView>
</xct:Popup>

**注意:**虽然我们可以使用Xamarin Community Toolkit的InvertedBoolConverter,但我已经描述了手动解决方案,以便我们可以添加自定义值转换器而不是内置转换器。

pw136qt2

pw136qt25#

我喜欢已经提供的答案,但我想我会添加我自己的版本,我一直在使用有时。在MVVM体系结构中,视图模型的属性都在对象设置器中调用SetProperty(),这会引发INotifyPropertyChanged事件。我所做的是向视图模型添加第二个属性,并在第一个属性的setter中将其值设置为!value
例如,只要属性ViewModel.IsBusy = true是这种情况,我就希望按钮是button.IsEnabled = false。这是一个反向的bool例子,就像你问的那样。
ViewModel.cs属性:

private bool enableButton;
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,解决了反向bool问题。

相关问题