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 - 否定布尔绑定值

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

Xamarin.Forms:MultiBinding IMultiValueConverter 接收 Null 值

Xamarin - 来自另一个页面/视图的 WebView 更新 URL

Xamarin iOS - XAML IsVisible 绑定在 ItemsSource 更改时不会更新

Xamarin.Forms:如何在 Xamarin.Forms 跨平台项目中开发具有蓝牙连接的应用程序?