尝试更新视图的筛选器时,ICollectionView.Source返回null. [英] ICollectionView.Source returns null when trying to update the View's Filter.
问题描述
我创建了一个ICollectionView:
Hi,
I have created an ICollectionView:
private ObervableCollection<Apples> MyCollection = new ObervableCollection<Apples>();
public ICollectionView View {get; private set; }
private void Init()
{
CollectionViewSource Cvs = new CollectionViewSource();
Cvs.Source = ObervableCollection;
View.Source = Cvs.View;
}
private void UpdateFilter(string Color)
{
using (View.DeferRefresh) // Not required
{
View.Filter = (o) = > {return ((Apple)(o)).Color = Color;}
}
}
代码编译错误可能在这里,我在另一台PC上..
问题是,当我从UI单击复选框以基于字符串重新应用过滤器时,当代码到达"View.Filter = ....."时,它将引发空引用异常(如果没有更多信息,则为您观察到,您可以看到View"SourceCollection"的属性为NULL).
正在执行的线程是MAIN线程.
我也尝试过使用Dispatcher中的Invoke或BeginInvoke,但是没有运气.
更多信息:
选中\取消选中UI中的复选框会更新绑定的后备属性ShowHide(Bool).
ShowHide调用UpdateFilter(string X),然后出现问题..
在此先感谢
Code compile errors might exist here, I''m on another PC..
The problem is that when i click a checkbox from the UI to reapply the filter based on a string, when the code reaches the "View.Filter = ....." it throws a null reference exception(with no more Info BUT if you observe you can see that the property of the View "SourceCollection" is NULL).
The Thread Executing is the MAIN thread..
I also tried using Invoke or BeginInvoke from the Dispatcher but with no luck..
More info:
Checking\Unchecking the checkbox from the Ui updates the binded backing property ShowHide(Bool).
The ShowHide Calls the UpdateFilter(string X) and then the problem occurs..
Thanks in advance
推荐答案
public class ViewModel
{
ObservableCollection<customer> CustomerList = new ObservableCollection<customer>();
public ICollectionView BlueCustomersView { get; private set; }
public ICollectionView BlackCustomersView { get; private set; }
public ICollectionView RedCustomersView { get; private set; } //UnBound
public ICollectionView CyanCustomersView { get; private set; } //UnBound
public ICollectionView PinkCustomersView { get; private set; } //UnBound
public ICollectionView OrangeCustomersView { get; private set; } //UnBound
public ViewModel()
{
for (int i = 0; i < 10000; i++)
{
Customer Cust = new Customer();
Cust.Name = i;
Cust.Color = (i % 2 == 0) ? Brushes.AliceBlue : Brushes.Black;
CustomerList.Add(Cust);
}
/****************************************************************************
* Move this Outside of the function to make things work
* *************************************************************************/
CollectionViewSource CvBlue = new CollectionViewSource();
CollectionViewSource CvBlack = new CollectionViewSource();
CollectionViewSource CvRed = new CollectionViewSource(); //UnBound
CollectionViewSource CvCyan = new CollectionViewSource(); //UnBound
CollectionViewSource CvPink = new CollectionViewSource(); //UnBound
CollectionViewSource CvOrange = new CollectionViewSource(); //UnBound
/***************************************************************************/
/************ Bound **************/
CvBlue.Source = CustomerList;
BlueCustomersView = CvBlue.View;
CvBlack.Source = CustomerList;
BlackCustomersView = CvBlack.View;
/************ **************/
/************ Un-Bound **************/
CvRed.Source = CustomerList;
RedCustomersView = CvRed.View;
CvCyan.Source = CustomerList;
CyanCustomersView = CvCyan.View;
CvPink.Source = CustomerList;
PinkCustomersView = CvPink.View;
CvOrange.Source = CustomerList;
OrangeCustomersView = CvOrange.View;
/************ **************/
}
public void ApplyFiltering()
{
//Bound CollectionViews
BlueCustomersView.Filter = (o) => { return ((Customer)o).Color == Brushes.AliceBlue; };
BlackCustomersView.Filter = (o) => { return ((Customer)o).Color == Brushes.Black; };
// Unbound CollectionViews
RedCustomersView.Filter = (o) => { return ((Customer)o).Color == Brushes.Red; };
CyanCustomersView.Filter = (o) => { return ((Customer)o).Color == Brushes.Cyan; };
PinkCustomersView.Filter = (o) => { return ((Customer)o).Color == Brushes.Pink; };
OrangeCustomersView.Filter = (o) => { return ((Customer)o).Color == Brushes.Orange; };
}
}
</customer></customer>
为了防止Framework处置CollectionViewSource,应将其设置为全局类变量,而不是函数内部的变量.
如果将CollectionViewSource的Property View绑定到某个地方,或者简单地说它具有引用,那么即使它不是全局的,也可以正常工作.
但是,一旦丢失,该框架可能就是GCing并销毁它.
我怀疑CollectionView的Source属性是WeakReference
CollectionViewSource的View属性.
TestProject的链接: https://docs.google.com/open?id=0B4xi5POVxsrxNDJnWnMxZ3p5VzA [ ^ ]
In order to keep the Framework from disposing the CollectionViewSource you should make it a global class variable and not a variable inside a function.
If the Property View of the CollectionViewSource is binded somewhere or let''s simple say that it has a reference things will work fine even if it''s not global.
However once lost the Framework is probably GCing and dispocing it.
I suspect that either the Source Property of a CollectionView is a WeakReference
either the View Property of a CollectionViewSource.
Link of TestProject : https://docs.google.com/open?id=0B4xi5POVxsrxNDJnWnMxZ3p5VzA[^]
请参见此处:
http://marlongrech.wordpress.com/2008/11/22/icollectionview-explained/ [ ^ ]
我认为您的问题是如何填充ICollectionView,应该这样完成:
See here:
http://marlongrech.wordpress.com/2008/11/22/icollectionview-explained/[^]
I think your problem is how you populate you ICollectionView, it should be done like this:
ICollectionView view = CollectionViewSource.GetDefaultView(myData);
这篇关于尝试更新视图的筛选器时,ICollectionView.Source返回null.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!