简体   繁体   English

如何从C#MVVM中绑定到ObservableCollection的列表中删除对象

[英]How to remove objects from a list bound to an ObservableCollection in C# MVVM

I'm trying to use the MVVM pattern in C#. 我正在尝试在C#中使用MVVM模式。 Therefore I have a customer class: 因此,我有一个客户类别:

public class Customer
{
    public string CustumerNumber { get; set; }
    public string CustomerName { get; set; }
}

I fill a list with Customers from a database: 我用数据库中的客户填充列表:

public class CustomerList
{
    public static List<Customer> customerlist = new List<Customer>();

    public static List<Customer> GetCustomer()
    {
    // Get data from database
    }
}

My ViewModel: 我的ViewModel:

class ViewModel : BaseViewModel
{
    public ObservableCollection<Customer> Customers { get; set; }
    public string CustomerSearch { get; set; }

    public ViewModel()
    {
         Customers = new ObservableColletion<Customers>(CustomerList.GetCustomer());
    }
}

I bound Customers in an WPF-ListBox: 我将客户绑定在WPF-ListBox中:

<ListBox ItemsSource="{Binding Customers}"
DisplayMemberPath="CustomerName"/>

Let's say I have 10 objects of CustomerName in the ListBox. 假设我在列表框中有10个CustomerName对象。 There is a TextBox that contains a string. 有一个包含字符串的TextBox。 Now I want to remove all objects in the ListBox that don't contain the string. 现在,我要删除列表框中所有不包含字符串的对象。 I solved the problem in the ViewModel as follows: 我解决了ViewModel中的问题,如下所示:

public void SearchCustomer()
{
    foreach (Customer item in Customers)
    {
        if (item.Customers.ToUpper().Contains(CustomerSearch.ToUpper()) == false)
        {
            this.Customers = new ObservableCollection<Customer>(CustomerList.RemoveItemsFromView(item));
        }
    }
}

Is this right? 这是正确的吗? It feels wrong to me, because every time the loop removes an item I create a new ObservableCollection instead of manipulating the existing one. 这对我来说是错的,因为每次循环删除一个项目时,我都会创建一个新的ObservableCollection而不是操纵现有的项目。 Is there a more professional way to solve this task? 有没有更专业的方法来解决此任务?

For the PropertyChangeEvent I use FodyWeaver 对于PropertyChangeEvent我使用FodyWeaver

由于您已经拥有“客户”项目,因此您可以在以下情况下执行此操作:

this.Customers.Remove(item) 

You should use the method Remove from Customers like you are doing with CustomerList . 您应该使用的方法RemoveCustomers喜欢你用做CustomerList Or update Customers after the loop: 或在循环后更新Customers

First Option 第一选择

foreach (Customer customer in Customers)
{
    if (!customer.Customers.ToUpper().Contains(CustomerSearch.ToUpper()))
    {
        CustomerList.RemoveItemsFromView(customer);
        Customers.Remove(customer);
    }
}

Second Option 第二种选择

foreach (Customer customer in Customers)
{
    if (!customer.Customers.ToUpper().Contains(CustomerSearch.ToUpper()))
    {
        CustomerList.RemoveItemsFromView(customer);
    }
}

this.Customers = new ObservableCollection<Customer>(CustomerList);

I can't suggest you more options without havig CustomerList and RemoveItemsFromView source code. 如果不浏览CustomerListRemoveItemsFromView源代码,我不能建议您更多选择。

Also, I refactored a bit the code. 另外,我重构了一些代码。 Having a good name for variables is important. 为变量起个好名字很重要。 And if looks a bit wrong, but I don't have your model. 如果看起来有点不对,但我没有您的模型。

If you don't want to create a new source collection, you could remove items from the existing one. 如果您不想创建新的源集合,则可以从现有的源集合中删除项目。 Just make sure that you don't call the Remove method in a foreach loop. 只要确保您没有在foreach循环中调用Remove方法即可。

This should work: 这应该工作:

for (int i = Customers.Count - 1; i >= 0; i--)
{
    Customer item = Customers[i];
    if (item.Customers.ToUpper().Contains(CustomerSearch.ToUpper()) == false)
    {
        Customers.RemoveAt(i);
    }
}

If you do reset the collection property each time you want to add or remove an item, you might as well use a List<T> . 如果每次要添加或删除项目时都要重置collection属性,则最好使用List<T> Just make sure that you raise a property notification when the property is set. 只需确保在设置属性时引发属性通知即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM