Xamarin Forms:IsVisible 绑定无法正常工作
Posted
技术标签:
【中文标题】Xamarin Forms:IsVisible 绑定无法正常工作【英文标题】:Xamarin Forms: IsVisible binding not working properly 【发布时间】:2021-06-25 17:58:36 【问题描述】:我正在尝试在用户交互中更新选项卡式页面的堆栈布局的可见性,并且反向布尔值似乎无法立即工作。我必须转到另一个页面并再次回来查看逆布尔转换器是否正常工作。任何人都可以建议我是否缺少任何东西。
XAML:
<page:ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:page="clr-namespace:My.Pages"
x:Class="Home"
xmlns:converter="clr-namespace:My.Pages.ValueConverters"
.....//....>
<StackLayout x:Name="stack1" Spacing="4" IsVisible="Binding IsSomethingVisible, Converter=x:Static converter:InverseBoolConverter.Create">
<Label Text="Hello" IsVisible="Binding IsSomethingelseVisible"/>
<Label Text="Hi" IsVisible="Binding IsSomethingelse2Visible"/>
</StackLayout>
<StackLayout x:Name="stack2" Spacing="4" IsVisible="Binding IsSomethingVisible">
<Label Text="Hello" IsVisible="Binding IsSomethingelseVisible"/>
<Label Text="Hi" IsVisible="Binding IsSomethingelse2Visible"/>
</StackLayout>
转换器:
public class InverseBoolConverter : IValueConverter
public static InverseBoolConverter Create
get
return new InverseBoolConverter();
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 !((bool)value);
视图模型:
private bool _isSomethingVisible;
public bool IsSomethingVisible
get return _isSomethingVisible;
set
_isSomethingVisible = value;
RaisePropertyChanged(nameof(IsSomethingVisible));
Public Void OnUserInteractionCommand()
DoSomething().ContinueWith((task) =>
Device.BeginInvokeOnMainThread(() => IsSomethingVisible = true;);
);
当前情景:
默认stack1
是可见的,但是当调用OnUserInteractionCommand
时stack2是可见的,stack1也是可见的,用户需要转到不同的页面再回来,然后stack2是可见的,stack1是不可见的。
预期:
当OnUserInteractionCommand
被调用时,stack2 应该是可见的,stack1 是不可见的。
【问题讨论】:
我看不出转换器有什么问题。为了确定问题出在哪里,您可以尝试以下测试:创建第二个属性IsOneVisible
,将其初始化为true
。在OnUserInteractionCommand
中,还设置IsOneVisible = false;
。并更改stack1
以使用IsVisible="Binding IsOneVisible"
。如果这有效,则证明问题与转换器有关。如果这不起作用,那么这是一个更微妙的问题 - 从哪里调用 OnUserInteractionCommand?一种可能的解决方法是在 UI 上以 100 毫秒的延迟调用。
【参考方案1】:
预期:调用 OnUserInteractionCommand 时,stack2 应该可见,而 stack1 不可见。
我修改了您关于转换器的代码并创建了简单的示例进行测试,没有问题。
<ContentPage
x:Class="FormsSample.simplecontrol.Page19"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:converter="clr-namespace:FormsSample.converter">
<ContentPage.Resources>
<converter:Visibleconverter x:Key="VisibleConverter" />
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<StackLayout x:Name="stack1" IsVisible="Binding IsSomethingVisible, Converter=StaticResource VisibleConverter">
<Label Text="Hello" />
<Label Text="Hi" />
<Label Text="stack1" />
</StackLayout>
<StackLayout x:Name="stack2" IsVisible="Binding IsSomethingVisible">
<Label Text="Hello" />
<Label Text="Hi" />
<Label Text="stack2" />
</StackLayout>
<Button
x:Name="btn1"
Clicked="btn1_Clicked"
Text="change visible" />
</StackLayout>
</ContentPage.Content>
Visibleconverter.cs:
public class Visibleconverter : 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)
throw new NotImplementedException();
我通过 button.click 更改 isSomethingVisible 值。
public partial class Page19 : ContentPage, INotifyPropertyChanged
private bool _isSomethingVisible;
public bool IsSomethingVisible
get return _isSomethingVisible;
set
_isSomethingVisible = value;
RaisePropertyChanged(nameof(IsSomethingVisible));
public Page19()
InitializeComponent();
this.BindingContext = this;
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
private void btn1_Clicked(object sender, EventArgs e)
Device.BeginInvokeOnMainThread(() => IsSomethingVisible = !IsSomethingVisible; );
【讨论】:
【参考方案2】:我不知道你想用这行代码做什么。
<StackLayout x:Name="stack1" Spacing="4" IsVisible="Binding IsSomethingVisible, Converter=x:Static converter:InverseBoolConverter.Create">
通常,您会在 App.xaml 中注册它,以便在整个应用程序中使用它。这不会是您最后一次需要反向布尔转换器。你也可以在页面资源中注册。
<ContentPage.Resources>
<converter:Visibleconverter x:Key="VisibleConverter" />
</ContentPage.Resources>
然后只需将转换器作为静态资源访问:
<StackLayout x:Name="stack1" IsVisible="Binding IsSomethingVisible, Converter=StaticResource VisibleConverter">
【讨论】:
以上是关于Xamarin Forms:IsVisible 绑定无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin Forms 两种方式绑定ActivityIndicator
Xamarin.Forms:MultiBinding IMultiValueConverter 接收 Null 值
Xamarin - 来自另一个页面/视图的 WebView 更新 URL