我正在编写一个简单的wpf应用程序,但我卡住了。我想实现,我有一个过滤器类,并且如果用户输入在过滤器类中更改了id,则列表应该刷新应用过滤器。所有初始绑定都有效。该列表与CompanyId一起正确显示。
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 {}
产品列表类:
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);
}
}
}
公司类(过滤器类):
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);
}
}
列表在工厂中刷新,但视图中没有变化。我可能做错了,也许我的整个方法并不是最好的。也许我必须使用带有valueconverter的ObservableCollection类型?任何帮助将不胜感激。干杯!
答案 0 :(得分:5)
使用ObservableCollection<Product>
代替根据IList
ObservableCollection
的目的是跟踪对集合的更改,并在集合发生更改时自动更新UI。
答案 1 :(得分:0)
您可能还考虑将ICollectionView用于此用例。
请参阅此post。