#xamarin #xamarin.forms
#xamarin #xamarin.forms
Вопрос:
Итак, я новичок в xamarin forms, и у меня проблема с моим listview. Итак, вот мой код.
Xaml:
<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#:
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 во всех своих объектах. Все мои коллекции доступны для наблюдения, и, как вы можете видеть, я тоже попробовал RefreshView. Я проверил весь свой код с точками останова и обнаружил, что все работает нормально, кроме моего списка. Дело в том, что обновленные данные есть, обновленные данные привязаны к MyContactList.ItemSource но мой список не будет обновляться, пока я не закрою страницу и не открою ее снова. Это из-за события OnAppearing()? пожалуйста, помогите мне: (
Извините, мой код сейчас в беспорядке, потому что я перепробовал все, что нашел в Интернете.
РЕДАКТИРОВАТЬ: вот как я добавляю контакт в mylist:
Кнопка является элементом панели инструментов, вот код:
<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);
}
}
in that page i have entries to enter the data then another toolbaritem to add the contact
<ContentPage.ToolbarItems>
<ToolbarItem IconImageSource="SubmitIcon.png" Text="ثبت" Order="Primary" Clicked="AddOrEditButton"/>
</ContentPage.ToolbarItems>
when clicked this happen
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);
}
And the command is
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 .
и метод RefreshList находится в моей ContactGroupingViewModel, это
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); }
}
}
Комментарии:
1. вы конкретно говорите, что проблема возникает при добавлении элемента, но вы не показали никакого кода, который это делает. Кроме того, вы имеете в виду, что нет такой вещи, как INotifyMeProperty
INotifyPropertyChanged
?2. да, я имел в виду, что один извините, я так устал в данный момент, что сейчас совершаю много ошибок. я отредактирую это. я могу показать вам код, но проблема возникает, когда я тоже удаляю контакт, и он не обновит список, пока я не выйду со страницы, но я уверен, что операции добавления и удаления работают нормально, потратив много времени на отладку и установив много точек останова, я увидел, что обновленныйданные привязаны к списку, но список не обновляется. я все еще могу отредактировать сообщение и добавить операции добавления и удаления, если вы хотите.
3. я отредактировал сообщение и добавил операцию добавления.
4. GroupedData должна быть ObservableCollection
5. это ObservableCollection.
Ответ №1:
Вам необходимо использовать ObservableCollection для уведомления ListView о любых изменениях.
Из документа:
Если вы хотите, чтобы ListView автоматически обновлялся по мере добавления, удаления и изменения элементов в базовом списке, вам необходимо использовать ObservableCollection . ObservableCollection определен в
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"});