从 ObservableCollection 中删除时未从 DataGrid 中删除项目
Item not removed from DataGrid when removing from ObservableCollection
当我从我的 ObservableCollection 中删除项目时,我很难更新数据网格。当我删除它们时,绑定到 DataGrid 的 ObservableCollection 中的项目被正确删除,但它们仍然出现在 DataGrid 中。
这是我的观点:
<Grid>
<DataGrid x:Name="ContactsList" Margin="20" AutoGenerateColumns="False" IsReadOnly="True" CanUserResizeRows="False"
CanUserResizeColumns="True" ColumnWidth="*" ItemsSource="{Binding Contacts, UpdateSourceTrigger=PropertyChanged, diag:PresentationTraceSources.TraceLevel=High}">
</DataGrid>
</Grid>
(列填充在代码隐藏中)。
这是我的视图模型:
public class ContactsViewModel : BindableBase
{
private readonly IRegionManager regionManager;
private readonly IEventAggregator eventAggregator;
private readonly IConfigurationContactsService contactsService;
private readonly DelegateCommand<object> deleteContactCommand;
private ObservableCollection<Contact> contactsCollection;
private ICollectionView contactsView;
public ContactsViewModel(IEventAggregator eventAggregator, IConfigurationContactsService contactsService, IRegionManager regionManager)
{
this.regionManager = regionManager;
this.contactsService = contactsService;
this.eventAggregator = eventAggregator;
this.deleteContactCommand = new DelegateCommand<object>(this.DeleteContact, this.CanDeleteContact);
this.contactsCollection = new ObservableCollection<Contact>(contactsService.GetContacts());
this.contactsView = CollectionViewSource.GetDefaultView(this.contactsCollection);
}
public ICollectionView ContactsView
{
get { return this.contactsView; }
}
public ObservableCollection<Contact> Contacts
{
get { return this.contactsCollection; }
}
public ICommand DeleteContactCommand
{
get { return this.deleteContactCommand; }
}
private void DeleteContact(object ignore)
{
IList<Contact> selectedContacts = contactsService.GetSelectedContacts();
foreach (Contact contact in selectedContacts)
{
if (contact != null)
{
contactsService.DeleteContact(contact);
}
}
SetProperty<ObservableCollection<Contact>>(ref this.contactsCollection, new ObservableCollection<Contact>(contactsService.GetContacts()), "Contacts");
// After this, the observable collection is updated correctly, but the datagrid does not delete the items.
}
private bool CanDeleteContact(object ignored)
{
return contactsService.GetSelectedContacts().Any();
}
}
我看不出错误在哪里。谁能发现错误?提前致谢。
编辑
这种观点有一个特点。有一个带有工具栏的主视图(删除按钮所在的位置),以及一个包含两个视图的 ContentTab 区域:视图 A、视图 B)。 DataGrid 位于视图 A 中,所有三个视图(A、B 和 MainView)都具有相同的视图模型:ContactsViewModel。
Observable 集合已经实现了 INotifyPropertyChanged,您不必再这样做:
public ObservableCollection<Contact> Contacts{ get;}
private void DeleteContact(object ignore)
{
IList<Contact> selectedContacts = contactsService.GetSelectedContacts();
foreach (Contact contact in selectedContacts)
{
if (contact != null)
{
contactsService.DeleteContact(contact);
Contacts.Remove(contact);// HERE IS THE CHANGE
}
}
}
您只需删除旧项目,并添加新项目。不需要另一个实例。
编辑:
要添加新项目,请执行以下操作:
Contacts.Add(newContact);
编辑编辑:
您可能需要稍微修改一下删除,试试这个:
Contacts.Remove(Contacts.FirstOrDefault(c=c.Id == contact.Id)); // HERE IS THE CHANGE
我不知道您的联系人 class 中是否有 ID 属性,如果没有,请使用其他方式查找正确的联系人,例如。名字或姓氏
当您拥有 ICollectionView 属性 时,为什么要绑定到 ObservableCollection?。无论如何,这应该刷新对 ObservableCollection 的绑定:
private void DeleteContact(object ignore)
{
IList<Contact> selectedContacts = contactsService.GetSelectedContacts();
foreach (Contact contact in selectedContacts)
{
if (contact != null)
{
contactsService.DeleteContact(contact);
}
}
contactsCollection = new ObservableCollection<Contact>(contactsService.GetContacts());
this.OnPropertyChanged("Contacts");
}
如果 DataGrid 没有得到更新,您需要验证 contactsService.GetContacts() 方法 return 是否包含您期望的项目 return。
编辑: 您还需要确保视图绑定到执行 DeleteContact 方法的视图模型的同一实例。在视图模型的构造函数中放置一个断点,并确保它只被命中一次。然后你知道只有一个实例被创建并且你绑定到这个实例。
当我从我的 ObservableCollection 中删除项目时,我很难更新数据网格。当我删除它们时,绑定到 DataGrid 的 ObservableCollection 中的项目被正确删除,但它们仍然出现在 DataGrid 中。
这是我的观点:
<Grid>
<DataGrid x:Name="ContactsList" Margin="20" AutoGenerateColumns="False" IsReadOnly="True" CanUserResizeRows="False"
CanUserResizeColumns="True" ColumnWidth="*" ItemsSource="{Binding Contacts, UpdateSourceTrigger=PropertyChanged, diag:PresentationTraceSources.TraceLevel=High}">
</DataGrid>
</Grid>
(列填充在代码隐藏中)。
这是我的视图模型:
public class ContactsViewModel : BindableBase
{
private readonly IRegionManager regionManager;
private readonly IEventAggregator eventAggregator;
private readonly IConfigurationContactsService contactsService;
private readonly DelegateCommand<object> deleteContactCommand;
private ObservableCollection<Contact> contactsCollection;
private ICollectionView contactsView;
public ContactsViewModel(IEventAggregator eventAggregator, IConfigurationContactsService contactsService, IRegionManager regionManager)
{
this.regionManager = regionManager;
this.contactsService = contactsService;
this.eventAggregator = eventAggregator;
this.deleteContactCommand = new DelegateCommand<object>(this.DeleteContact, this.CanDeleteContact);
this.contactsCollection = new ObservableCollection<Contact>(contactsService.GetContacts());
this.contactsView = CollectionViewSource.GetDefaultView(this.contactsCollection);
}
public ICollectionView ContactsView
{
get { return this.contactsView; }
}
public ObservableCollection<Contact> Contacts
{
get { return this.contactsCollection; }
}
public ICommand DeleteContactCommand
{
get { return this.deleteContactCommand; }
}
private void DeleteContact(object ignore)
{
IList<Contact> selectedContacts = contactsService.GetSelectedContacts();
foreach (Contact contact in selectedContacts)
{
if (contact != null)
{
contactsService.DeleteContact(contact);
}
}
SetProperty<ObservableCollection<Contact>>(ref this.contactsCollection, new ObservableCollection<Contact>(contactsService.GetContacts()), "Contacts");
// After this, the observable collection is updated correctly, but the datagrid does not delete the items.
}
private bool CanDeleteContact(object ignored)
{
return contactsService.GetSelectedContacts().Any();
}
}
我看不出错误在哪里。谁能发现错误?提前致谢。
编辑
这种观点有一个特点。有一个带有工具栏的主视图(删除按钮所在的位置),以及一个包含两个视图的 ContentTab 区域:视图 A、视图 B)。 DataGrid 位于视图 A 中,所有三个视图(A、B 和 MainView)都具有相同的视图模型:ContactsViewModel。
Observable 集合已经实现了 INotifyPropertyChanged,您不必再这样做:
public ObservableCollection<Contact> Contacts{ get;}
private void DeleteContact(object ignore)
{
IList<Contact> selectedContacts = contactsService.GetSelectedContacts();
foreach (Contact contact in selectedContacts)
{
if (contact != null)
{
contactsService.DeleteContact(contact);
Contacts.Remove(contact);// HERE IS THE CHANGE
}
}
}
您只需删除旧项目,并添加新项目。不需要另一个实例。
编辑:
要添加新项目,请执行以下操作:
Contacts.Add(newContact);
编辑编辑:
您可能需要稍微修改一下删除,试试这个:
Contacts.Remove(Contacts.FirstOrDefault(c=c.Id == contact.Id)); // HERE IS THE CHANGE
我不知道您的联系人 class 中是否有 ID 属性,如果没有,请使用其他方式查找正确的联系人,例如。名字或姓氏
当您拥有 ICollectionView 属性 时,为什么要绑定到 ObservableCollection?。无论如何,这应该刷新对 ObservableCollection 的绑定:
private void DeleteContact(object ignore)
{
IList<Contact> selectedContacts = contactsService.GetSelectedContacts();
foreach (Contact contact in selectedContacts)
{
if (contact != null)
{
contactsService.DeleteContact(contact);
}
}
contactsCollection = new ObservableCollection<Contact>(contactsService.GetContacts());
this.OnPropertyChanged("Contacts");
}
如果 DataGrid 没有得到更新,您需要验证 contactsService.GetContacts() 方法 return 是否包含您期望的项目 return。
编辑: 您还需要确保视图绑定到执行 DeleteContact 方法的视图模型的同一实例。在视图模型的构造函数中放置一个断点,并确保它只被命中一次。然后你知道只有一个实例被创建并且你绑定到这个实例。