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

Posted

技术标签:

【中文标题】Xamarin iOS - XAML IsVisible 绑定在 ItemsSource 更改时不会更新【英文标题】:Xamarin iOS - XAML IsVisible binding does not update when ItemsSource is changed 【发布时间】:2021-12-01 08:37:00 【问题描述】:

我在 XAML 中有一个绑定,它作为 ItemsSource 链接到对象列表。在 android 上,当我更新 ItemsSource 时,它​​会成功更新 XAML 中的绑定。

但是在 ios 上,由于某种原因,这不起作用。谁能提出原因?

ItemsSource 的初始声明:

users.ItemsSource = new System.Collections.ObjectModel.ObservableCollection<AccountGroup>(Accounts);

更新 ItemsSource 的 CS 代码:

            users.ItemsSource = null;
            users.ItemsSource = new System.Collections.ObjectModel.ObservableCollection<AccountGroup>(Accounts);

这是帐户组对象:

public class Account : INotifyPropertyChanged
    
        public string student_unique_id  get; set; 

        public string student_fullname  get; set; 

        public string organisation_id  get; set; 

        public string organisation_title  get; set; 

        public string student_token  get;set;

        public string reg_branding_url  get;set;

        public string tint_colour  get;set;

        public string font_colour  get;set;

        public string topup_product_id  get;set;

        public bool isVisible  get; set; 

        public string student_initial 
         
            get
            
                return student_fullname[0].ToString();
             
        

        public string school_image
        
            get
            
                return $"Constants.apiBaseUrlstore/images/uploaded/mobile/reg_branding_url";
            
        

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        
    

    public class AccountGroup : List<Account>, INotifyPropertyChanged
    
        public string organisation_title  get; set; 
        public string school_image  get; set; 
        public string tint_colour  get; set; 

        public string font_colour  get; set; 

        public AccountGroup(string orgTitle, string orgImage, string orgTint, string orgFont, List<Account> accounts) : base(accounts)
        
            organisation_title = orgTitle;
            school_image = orgImage;
            tint_colour = orgTint;
            font_colour = orgFont;
        

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        
    

这是具有 IsVisible 属性的 XAML:

        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout>
                <Frame IsVisible="Binding isVisible" IsEnabled="False" HasShadow="True" BackgroundColor="White" Padding="0">
                    <Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
                        <behaviors:Expander x:Name="MainExpander" CollapseAnimationLength="500" IsExpanded="False" IsVisible="True" >

谁能建议如何解决这个问题?看起来很奇怪,它适用于 Android 而不是 iOS。谢谢!

【问题讨论】:

只有IsVisible没有更新吗?其他属性是否更新?您是否尝试过在 MainThread 上强制更新? 您正在实施INotifyPropertyChanged,但您从未调用OnPropertyChanged。奇怪的是它可以在 Android 上运行。此外,将 ItemSource 设置为 Null 并设置一个新的也不是一个好习惯 Jason - 似乎没有任何属性更新。我在主线程上试过了。 【参考方案1】:

从文档From Data Bindings to MVVM,我们知道:

ViewModels 一般实现 INotifyPropertyChanged 接口, 这意味着该类在任何时候触发一个 PropertyChanged 事件 其属性的变化。 Xamarin.Forms 中的数据绑定机制 将处理程序附加到此 PropertyChanged 事件,以便通知它 当属性更改并使用新的更新目标时 价值。

在代码Account.cs 中,你实现了接口INotifyPropertyChanged,但是你没有调用OnPropertyChanged。所以即使值改变了,UI也不会刷新。

可以参考以下代码:

 public class Account: INotifyPropertyChanged

    string _student_fullname;
    public string student_fullname
    
        set  SetProperty(ref _student_fullname, value); 

        get  return _student_fullname; 
    

    private bool _isVisible;
    public bool isVisible
    
        set  SetProperty(ref _isVisible, value); 
        get  return _isVisible; 
    

// you can modify other codes to trigger `SetProperty` just as above code


    bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    
        if (Object.Equals(storage, value))
            return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    

    public event PropertyChangedEventHandler PropertyChanged;

注意:

您可以修改类Account中的其他字段来触发SetProperty,就像上面的代码一样。与AccountGroup.cs 类相同

另外,你可以为你的users.ItemsSource定义一个全局变量,例如:

   public ObservableCollection<AccountGroup> items  get; private set; 

并将其初始化如下:

   items = new ObservableCollection<AccountGroup>();

ItemsSource 的初始声明:

 users.ItemsSource = items;

在这种情况下,如果您希望collectionview在基础列表中添加、删除和更改项目时自动更新,我们需要使用ObservableCollection。我们不需要以下代码:

users.ItemsSource = null;
            users.ItemsSource = new System.Collections.ObjectModel.ObservableCollection<AccountGroup>(Accounts);

【讨论】:

以上是关于Xamarin iOS - XAML IsVisible 绑定在 ItemsSource 更改时不会更新的主要内容,如果未能解决你的问题,请参考以下文章

来自 xaml 的自定义渲染器的 Xamarin 访问属性

Xamarin XAML语言教程Xamarin.Forms中改变活动指示器颜色

是否可以将 Xaml 设计器或智能感知与 Xamarin.Forms 一起使用?

Xamarin.UWP应用程序无法启动,因为无法加载“Microsoft.Graphics.Canvas.UI.Xaml.CanvasImageSource”

使用 ShellContent xamarin 表单时添加导航返回箭头

Visual Studio 2019 和 Xamarin iOS - 模拟器问题