如何在c#中刷新数据绑定集合?

时间:2022-08-24 13:08:21

Im writing a simple wpf application, but Im stuck. I'd like to achieve, that I have a filter class, and If the id has been changed in the filter class by a user input, a list should refresh applying the filter. All the initial bindings are working. The list is displayed properly along with the CompanyId.

我正在写一个简单的wpf应用程序,但我卡住了。我想实现,我有一个过滤器类,并且如果用户输入在过滤器类中更改了id,则应该刷新应用过滤器的列表。所有初始绑定都有效。该列表与CompanyId一起正确显示。

the databinding in xaml:

xaml中的数据绑定:

<ListBox Height="212" HorizontalAlignment="Left" Margin="211,31,0,0" Name="listBoxProducts" VerticalAlignment="Top" Width="267" ItemsSource="{Binding ElementName=this, Path=Products}" DisplayMemberPath="CompanyId" />  
<TextBox Height="28" HorizontalAlignment="Left" Margin="12,31,0,0" Name="textBoxCompanyId" VerticalAlignment="Top" Width="170" Text="{Binding ElementName=this, Path=Company.Id}" />

The code-behind for the xaml:

xaml的代码隐藏:

private TestFactory _testFactory  = new TestFactory();

    private Company _company;
    public Company Company
    {
        get { return _company; }
    }

    private IProductList _products;
    public IProductList Products
    {
        get { return _products; }
    }


    public MainWindow()
    {
        _company = _testFactory.Company;
        _products = _testFactory.Products;

        InitializeComponent();
        _company.FilterChanged += _testFactory.FilterChanging;
    }

The (dummy)factory class:

(虚拟)工厂类:

private IProductList _products;
    public IProductList Products 
    {
        get { return _products; }
    }

    private Company _company = new Company();
    public Company Company
    {
        get { return _company; }
    }

    public TestFactory()
    {
        _company = new Company() { Id = 2, Name = "Test Company" };
        GetProducts();
    }

    public void GetProducts()
    {
        var products = new List<Product>();
        products.Add(new Product() { ProductNumber = 1, CompanyId = 1, Name = "test product 1" });
        products.Add(new Product() { ProductNumber = 2, CompanyId = 1, Name = "test product 2" });
        products.Add(new Product() { ProductNumber = 3, CompanyId = 2, Name = "test product 3" });

        if (Company.Id != 2)
        {
            products = products.Where(p => p.CompanyId == Company.Id).ToList();
        }

        _products = new ProductList(products);
    }

    public void FilterChanging(object sender, EventArgs e)
    {
        GetProducts();
    }

The ProductList interface:

ProductList接口:

public interface IProductList : IList<Product>, INotifyCollectionChanged {}

The productlist class:

productlist类:

public class ProductList : IProductList
{
    private readonly IList<Product> _products;

    public ProductList() { }

    public ProductList(IList<Product> products)
    {
        _products = products;
    }


    public IEnumerator<Product> GetEnumerator()
    {
        return _products.GetEnumerator();
    }


    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }


    public void Add(Product item)
    {
        _products.Add(item);
        notifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
    }


    public void Clear()
    {
        _products.Clear();
        notifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }


    public bool Contains(Product item)
    {
        return _products.Contains(item);
    }


    public void CopyTo(Product[] array, int arrayIndex)
    {
        _products.CopyTo(array, arrayIndex);
    }


    public bool Remove(Product item)
    {
        var removed = _products.Remove(item);

        if (removed)
        {
            notifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
        }
        return removed;
    }


    public int Count
    {
        get { return _products.Count; }
    }


    public bool IsReadOnly
    {
        get { return _products.IsReadOnly; }
    }


    public int IndexOf(Product item)
    {
        return _products.IndexOf(item);
    }


    public void Insert(int index, Product item)
    {
        _products.Insert(index, item);
        notifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }


    public void RemoveAt(int index)
    {
        _products.RemoveAt(index);
        notifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }


    public Product this[int index]
    {
        get { return _products[index]; }
        set
        {
            _products[index] = value;
            notifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, _products[index]));
        }
    }


    public event NotifyCollectionChangedEventHandler CollectionChanged;
    private void notifyCollectionChanged(NotifyCollectionChangedEventArgs args)
    {
        if (CollectionChanged != null)
        {
            CollectionChanged(this, args);
        }
    }
}

The Company class (filter class):

公司类(过滤器类):

public class Company : INotifyPropertyChanged
{
    private int _id;
    public int Id
    {
        get { return _id; }
        set 
        {
            if (_id == value)
                return;

            _id = value;
            OnPropertyChanged("Id");

            OnFilterChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name == value)
                return;

            _name = value;
            OnPropertyChanged("Name");
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;
    public event EventHandler FilterChanged;

    private void OnPropertyChanged(string name)
    {
        if (PropertyChanged == null)
            return;

        var eventArgs = new PropertyChangedEventArgs(name);
        PropertyChanged(this, eventArgs);
    }

    private void OnFilterChanged(NotifyCollectionChangedEventArgs e)
    {
        if (FilterChanged == null)
            return;

        FilterChanged(this, e);
    }
}

The list is refreshed in factory, but there is no change in the view. I probably do something wrong, maybe my whole approach is not best. Maybe I have to use ObservableCollection type with valueconverter? Any help would be greatly appreciated. Cheers!

该列表在工厂中刷新,但视图中没有更改。我可能做错了,也许我的整个方法并不是最好的。也许我必须使用带有valueconverter的ObservableCollection类型?任何帮助将不胜感激。干杯!

2 个解决方案

#1


5  

Use an ObservableCollection<Product> instead of creating your own list based on IList

使用ObservableCollection 而不是基于IList创建自己的列表

The purpose of an ObservableCollection is to track changes to the collection, and it will automatically update the UI when the collection changes.

ObservableCollection的目的是跟踪对集合的更改,并在集合更改时自动更新UI。

#2


0  

You might also consider using ICollectionView for this use-case.

您也可以考虑将ICollectionView用于此用例。

Refer this post.

请参阅这篇文章。

#1


5  

Use an ObservableCollection<Product> instead of creating your own list based on IList

使用ObservableCollection 而不是基于IList创建自己的列表

The purpose of an ObservableCollection is to track changes to the collection, and it will automatically update the UI when the collection changes.

ObservableCollection的目的是跟踪对集合的更改,并在集合更改时自动更新UI。

#2


0  

You might also consider using ICollectionView for this use-case.

您也可以考虑将ICollectionView用于此用例。

Refer this post.

请参阅这篇文章。