从ObservableCollection中删除时,项目未从DataGrid中删除

时间:2017-01-02 08:02:59

标签: wpf binding datagrid prism observablecollection

当我从ObservableCollection中删除项目时,我正在努力更新datagrid。当我删除它们时,ObservableCollection中绑定到DataGrid的项目将被正确删除,但它们仍然出现在DataGrid中。

这是我的观点:

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();
    }       
}

(列在代码隐藏中填充。)

这是我的观点模型:

PS C:\Users\steve> Get-WinEvent -Log System | where {($_.ID -eq "12" -or $_.ID -eq "13")} | format-table -property Message

Message
-------
The operating system started at system time ?2017?-?01?-?01T00:51:20.610798500Z.
The operating system is shutting down at system time ?2017?-?01?-?01T00:50:53.812034600Z.

我看不出错误在哪里。谁能发现错误?提前谢谢。

修改

这种观点有一个特点。有一个带有工具栏的主视图(删除按钮所在的位置),以及一个包含两个视图的ContentTab区域:视图A,视图B)。 DataGrid位于View A中,所有的thre视图(A,B和MainView)都具有相同的viewmodel:ContactsViewModel。

2 个答案:

答案 0 :(得分:0)

Observable collection已经实现了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

我不知道您的联系人类中是否有ID属性,如果没有,则使用其他内容来查找正确的联系人,例如。姓名或姓氏

答案 1 :(得分:0)

为什么在拥有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()方法是否返回您希望它返回的项目。

编辑:您还需要确保视图绑定到执行DeleteContact方法的视图模型的同一实例。在视图模型的构造函数中放置一个断点,并确保它只被命中一次。然后你知道只创建了一个实例,并且你绑定到这个实例。