3

私は単純なwpfアプリケーションを書いていますが、私は固執しています。私は達成したいと思います、私はフィルタクラスを持っている、そして、IDがフィルタクラスでユーザー入力によって変更されている場合、リストはフィルタを適用して更新する必要があります。すべての初期バインディングが機能しています。このリストは、CompanyIdと共に適切に表示されます。C#でデータバインドされたコレクションを更新するには?

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}" /> 

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

(ダミー)ファクトリクラス:

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

ProductListインタフェース:

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

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

Companyクラス(フィルタークラス):

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

リストは、工場でリフレッシュが、ビューに変化はありません。私はおそらく何か間違っている、おそらく私の全体のアプローチは最善ではない。たぶん私はObservableCollection型をvalueconverterで使用する必要がありますか?どんな助けでも大歓迎です。乾杯!

答えて

5

利用代わりObservableCollectionの目的は、コレクションへの変更を追跡することであり、それは自動的にコレクションが変更UIを更新しますIList

をもとに、独自のリストを作成するObservableCollection<Product>

+0

ObservableCollection を実装したいのであれば、ValueConverterが必要かどうか? – JahManCan

+0

@JahManCanいいえ、あなたはいません – Rachel

+0

ビューに通知するためにイベントに登録する関数が必要ですか?コレクションに何らかの変更があったかどうか? btw私は私の問題の解決策を見つけましたが、私はまだよく分かりません。 GetProducts()を次のように変更した場合: ... if(_products!= null) { _products.Clear(); (製品=>製品.com).ToList()。 } else { _products = products; } あなたはどう思いますか? – JahManCan

0

また、このユースケースでICollectionViewを使用することを検討することもできます。

これはpostを参照してください。

+0

私はむしろこのアプローチを避け、この仕事をする方法。 – JahManCan

関連する問題