MyListView 不会更新 Xamarin 表单

问题描述

所以我是 xamarin 表单的新手,我的列表视图有问题。所以这是我的代码

XML:

    <RefreshView x:Name="MyContactRefreshView">
    <ListView x:Name="MyContactList"
        Margin="5"   
        ItemsSource="{Binding GroupedData}" 
        IsGroupingEnabled="True"        
        GroupdisplayBinding="{Binding Key}"
        HasUnevenRows="True"
        ItemTapped="GoToContactDetail"
        >
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextCell Text="{Binding Name}" Detail="{Binding Phone1}" x:Name="ContactItem"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    </RefreshView>

这是我在 C# 中的 contactList 页面代码

    public partial class ContactList : ContentPage
    {
        private readonly ContactListGroupingviewmodel _contacts;
        private bool _myContactListItemSourceIsBound;
        public ICommand RefreshCommand { get { return new Command(async() => await RefreshList()); } }

        public ContactList()
        {
            InitializeComponent();
            _contacts = new ContactListGroupingviewmodel();
            MyContactRefreshView.Command = RefreshCommand;
            MyContactRefreshView.IsRefreshing = App.viewmodel.isBusy;
            _myContactListItemSourceIsBound = false;
        }
        protected override void OnAppearing()
        {
            MyContactRefreshView.IsRefreshing = true;
            base.OnAppearing();
        }
        private void GoToContactDetail(object sender,ItemTappedEventArgs e)
        {
            new DataLayer.Cummon.Commands.NavigatetoContactCommand().Execute(e.Item as ContactObservableModel);
        }
        public async Task RefreshList()
        {
            MyContactRefreshView.IsRefreshing = true;
            MyContactList.SelectedItem = null;
            await _contacts.RefreshList();
            if (_myContactListItemSourceIsBound == false)
            {
                MyContactList.ItemsSource = _contacts.GroupedData;
                _myContactListItemSourceIsBound = true;
            }
            MyContactRefreshView.IsRefreshing = false;
        }
    }

所以问题是我有这个按字母顺序排列的联系人列表视图。我有这个添加按钮,可以导航到联系人添加编辑页面添加联系人后,它会再次返回到此页面。因此,在返回此页面后,它不会更新列表。我一直在寻找几天。我在所有对象中都实现了 INotifyPropertyChanged。我所有的集合都是 Observable 的,正如你所看到的,我也尝试过 RefreshView。我用断点检查了我的整个代码,我发现除了我的列表之外一切正常。问题是更新的数据在那里,更新的数据绑定到 MyContactList.ITemSource 但我的列表不会更新,直到我关闭页面并再次打开它。是因为 OnAppearing() 事件吗?请帮帮我:(

抱歉,我的代码现在一团糟,因为我一直在尝试我在互联网上找到的所有内容

编辑:这是我向我的列表添加联系人的方式:

Button 是一个 ToolbarItem 代码如下:

    <ContentPage.toolbaritems>
        <ToolbarItem Text="افزودن مخاطب" IconImageSource="AddIcon.png" Command="{StaticResource NavigatetoContactAddOrEditPageCommand}" Order="Primary"/>
    </ContentPage.toolbaritems>

当点击这个命令被执行,然后去联系添加编辑页面

    public class NavigatetoContactAddOrEditPageCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            return true;
        }
        public void RaiseCanExecuteChanged()
        {
            var handler = CanExecuteChanged;
            if (handler != null)
            {
                handler(this,EventArgs.Empty);
            }
        }

        public void Execute(object parameter)
        {
            NavigateAsync();
        }
        public async void NavigateAsync()
        {
            await App.MainNavigation.PushAsync(new Pages.ContactAddOrEditPage(),true);
        }
    }

在该页面中,我有条目可以输入数据,然后是另一个工具栏项来添加联系人

        <ContentPage.toolbaritems>
        <ToolbarItem IconImageSource="SubmitIcon.png" Text="ثبت" Order="Primary" Clicked="AddOrEditButton"/>
    </ContentPage.toolbaritems>

点击时发生

        private void AddOrEditButton(object sender,EventArgs e)
        {
            ContactObservableModel target = new ContactObservableModel()
            {
                Name = contactName.Text,Phone1 = contactPhone1.Text,Phone2 = contactPhone2.Text,AccountNumber = contactAccountNumber.Text,Phonesocial = contactPhone2.Text
            };
            new DataLayer.Cummon.Commands.AddToContactsCommand().Execute(target);
       }

命令是

 public class AddToContactsCommand : ICommand
    {
        private bool _isBusy = false;
        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            return !_isBusy;
        }
        public void RaiseCanExecuteChanged()
        {
            var handler = CanExecuteChanged;
            if (handler != null)
            {
                handler(this,EventArgs.Empty);
            }
        }

        public void Execute(object parameter)
        {
            AddToContacts(parameter as ContactObservableModel);
            App.MainNavigation.PopAsync();
        }
        public async void AddToContacts(ContactObservableModel contact)
        {
            this._isBusy = true;
            this.RaiseCanExecuteChanged();
            App.viewmodel.isBusy = true;
            await App.viewmodel.ContactListAsync.AddAsync(contact);
            this._isBusy = false;
            this.RaiseCanExecuteChanged();
            App.viewmodel.isBusy = false;
        }
    }

然后它被添加数据库中,现在我必须调用我的刷新列表方法

        public async Task RefreshList()
        {
            this.Items.Clear();
            this.GroupedData.Clear();
            await App.viewmodel.GetContactsItemsAsync();
            var contacts = App.viewmodel.ContactListAsync.OrderBy(n => n.Name).ToList();
            foreach (var contact in contacts)
            {
                this.Items.Add(contact);
            }
            var groupedContacts = Items.OrderBy(p => p.Name)
               .GroupBy(p => p.Name[0].ToString())
               .Select(p => new ObservableGroupCollection<string,ContactObservableModel>(p)).ToList();
            foreach (var contact in groupedContacts)
            {
                this.GroupedData.Add(contact);
            }
        }

并且列表绑定到 GroupedData 属性。 我的 ContactGroupingviewmodel 上的 RefreshList 方法是这个

    class ContactListGroupingviewmodel : ObservableBase
    {
        public ContactListGroupingviewmodel()
        {
            Items = new ObservableCollection<ContactObservableModel>();
            GroupedData = new List<ObservableGroupCollection<string,ContactObservableModel>>();
        }
        public async Task RefreshList()
        {
            this.Items.Clear();
            this.GroupedData.Clear();
            await App.viewmodel.GetContactsItemsAsync();
            var contacts = App.viewmodel.ContactListAsync.OrderBy(n => n.Name).ToList();
            foreach (var contact in contacts)
            {
                this.Items.Add(contact);
            }
            var groupedContacts = Items.OrderBy(p => p.Name)
               .GroupBy(p => p.Name[0].ToString())
               .Select(p => new ObservableGroupCollection<string,ContactObservableModel>(p)).ToList();
            foreach (var contact in groupedContacts)
            {
                this.GroupedData.Add(contact);
            }
        }
        private IList<ContactObservableModel> _items;
        public IList<ContactObservableModel> Items
        {
            get { return _items; }
            set { this.SetProperty(ref this._items,value); }
        }
        private List<ObservableGroupCollection<string,ContactObservableModel>> _groupedData;
        public List<ObservableGroupCollection<string,ContactObservableModel>> GroupedData
        {
            get { return _groupedData; }
            set { this.SetProperty(ref this._groupedData,value); }
        }
    }

解决方法

您需要使用 ObservableCollection 将任何更改通知 ListView。

来自document

如果您希望 ListView 在添加项目时自动更新, 在基础列表中删除和更改,您需要使用 ObservableCollectionObservableCollection 定义在 System.Collections.ObjectModel 和 List 一样,除了它 可以通知 ListView 任何更改:

ObservableCollection<Employee> employees = new ObservableCollection<Employee>();
listView.ItemsSource = employees;

//Mr. Mono will be added to the ListView because it uses an ObservableCollection
employees.Add(new Employee(){ DisplayName="Mr. Mono"});