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