【问题标题】:Xamarin iOS - XAML IsVisible binding does not update when ItemsSource is changedXamarin iOS - XAML IsVisible 绑定在 ItemsSource 更改时不会更新
【发布时间】:2023-03-09 20:03:01
【问题描述】:

我在 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。谢谢!

【问题讨论】:

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

标签: c# xamarin xamarin.forms data-binding


【解决方案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);

【讨论】:

    猜你喜欢
    • 2020-03-28
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 2012-06-22
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多