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

Xamarin iOS - XAML IsVisible binding does not update when ItemsSource is changed

我在 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.apiBaseUrl}store/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 似乎很奇怪。谢谢!

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

ViewModels generally implement the INotifyPropertyChanged interface, which means that the class fires a PropertyChanged event whenever one of its properties changes. The data binding mechanism in Xamarin.Forms attaches a handler to this PropertyChanged event so it can be notified when a property changes and keep the target updated with the new value.

在代码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;
}

注:

您可以修改class中的其他字段Account来触发SetProperty,就像上面的代码一样。与 class 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);