C# Silverlight中基于Linq查询的Collection/CollectionView
我正在研究绑定到ObservableCollection属性的概念证明,该属性返回委托的结果。委托还为其设置了一个属性,这样我就可以更改所使用的表达式,并为集合触发OnPropertyChanged。这允许我将组合框绑定到集合,并且在更改表达式/查询时,组合框中的可用选项也将更改 代码:C# Silverlight中基于Linq查询的Collection/CollectionView,c#,linq,silverlight,delegates,observablecollection,C#,Linq,Silverlight,Delegates,Observablecollection,我正在研究绑定到ObservableCollection属性的概念证明,该属性返回委托的结果。委托还为其设置了一个属性,这样我就可以更改所使用的表达式,并为集合触发OnPropertyChanged。这允许我将组合框绑定到集合,并且在更改表达式/查询时,组合框中的可用选项也将更改 代码: 公共委托列表Del(); 私有Del_查询; 公共数据查询 { 收到 { 返回查询; } 设置 { _查询=值; OnPropertyChanged(“绑定列表”); } } 私有可观察收集绑定列表; 公共可观
公共委托列表Del();
私有Del_查询;
公共数据查询
{
收到
{
返回查询;
}
设置
{
_查询=值;
OnPropertyChanged(“绑定列表”);
}
}
私有可观察收集绑定列表;
公共可观测集合绑定列表
{
收到
{
var results=Query();
bindList=新的可观察收集(结果);
返回绑定列表;
}
设置
{//我相信我需要这个setter来实现清单上的ObservableCollections提供的额外功能
if(bindList!=值){
bindList=值;
OnPropertyChanged(“绑定列表”);
}
}
}
由于这是可行的,我想用它创建一个简单的类来绑定。我在寻求如何这样做的指导。我曾经考虑过将ObservaleCollection子类化,但在如何设置项方面遇到了问题。我还考虑了使用IEnumerable和ICollectionView等接口(以及通知接口)的自定义类
总之,您将如何构建一个类来合并一个集合,该集合的成员基于关于子类化/接口的委托查询(具体来说是LINQ)
提前谢谢。这是我到目前为止的想法。还没有进行过很多测试,但到目前为止,它看起来相当不错
public class DynamicCollection<T> : IEnumerable, INotifyCollectionChanged
{
public ICollectionView Collection { get; private set; }
public delegate List<T> Del();
private Del query;
public Del Query
{
get
{
return query;
}
set
{
if (query != value)
{
query = value;//set the new query
T currentItem = (T)Collection.CurrentItem;//save current item
Collection = new PagedCollectionView(Query());//recreate collection with new query
Collection.MoveCurrentTo(currentItem);//move current to the previous current (if it doesn't exist, nothing is selected)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));//Notify colleciton has changed.
}
}
}
public DynamicCollection()
{
Collection = new PagedCollectionView(new List<T>());//empty collection
}
public DynamicCollection(IEnumerable<T>collection)
{
Collection = new PagedCollectionView(collection);
}
public DynamicCollection(Del delegateQuery)
{
Query = delegateQuery;
}
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
return Collection.GetEnumerator();
}
#endregion IEnumerable Members
#region INotifyCollectionChanged Members
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler handler = CollectionChanged;
if (handler != null)
{
CollectionChanged(this, e);
}
}
#endregion INotifyCollectionChanged Members
}
公共类DynamicCollection:IEnumerable,InotifyCollection已更改
{
公共ICollectionView集合{get;private set;}
公共委托列表Del();
私有Del查询;
公共数据查询
{
收到
{
返回查询;
}
设置
{
if(查询!=值)
{
query=value;//设置新查询
T currentItem=(T)Collection.currentItem;//保存当前项
Collection=new PagedCollectionView(Query());//使用新查询重新创建集合
Collection.MoveCurrentTo(currentItem);//将当前移动到上一个当前(如果它不存在,则不选择任何内容)
OnCollectionChanged(新建NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));//通知集合已更改。
}
}
}
公共动态集合()
{
Collection=new PagedCollectionView(new List());//空集合
}
公共动态集合(IEnumerablecollection)
{
集合=新页面集合视图(集合);
}
公共DynamicCollection(Del delegateQuery)
{
查询=委托查询;
}
#区域可数成员
公共IEnumerator GetEnumerator()
{
返回集合。GetEnumerator();
}
#endregion可数成员
#区域INotifyCollectionChanged成员
公共事件通知CollectionChangedEventHandler CollectionChanged;
CollectionChanged上受保护的void(NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler处理程序=CollectionChanged;
if(处理程序!=null)
{
集合更改(本,e);
}
}
#endregion INotifyCollectionChanged成员
}
可以使用组合框中的ItemsSource=“{Binding Path=myCollection,Mode=TwoWay}”
将其绑定到(假设您在ViewModel/数据上下文中将dyamicollection myCollection设置为属性)
这一切都是通过设置查询来实现的,在我的例子中,我给出了一个LINQ to XML查询,该查询返回一个列表。集合在此基础上更新,绑定组合框反映此更新
请随意评论这一点。我相当肯定我已经成功了,或者也许有更好的方法来做到这一点。我愿意接受反馈,并将随着答案的发展不断更新。ICollectionView
看起来是答案的一部分。它有一个SourceCollection的只读属性,我认为它应该引用类中的私有列表?除非我也从某个集合类继承,否则当我尝试绑定到我的类时,我不必绑定到myCollection.SourceCollection
,或者绑定到myCollection
就足够了(myCollection是我自定义类的类型)。我宁愿不做点语法,因为我会有很多这样的语法,它只会变得杂乱无章。
public class DynamicCollection<T> : IEnumerable, INotifyCollectionChanged
{
public ICollectionView Collection { get; private set; }
public delegate List<T> Del();
private Del query;
public Del Query
{
get
{
return query;
}
set
{
if (query != value)
{
query = value;//set the new query
T currentItem = (T)Collection.CurrentItem;//save current item
Collection = new PagedCollectionView(Query());//recreate collection with new query
Collection.MoveCurrentTo(currentItem);//move current to the previous current (if it doesn't exist, nothing is selected)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));//Notify colleciton has changed.
}
}
}
public DynamicCollection()
{
Collection = new PagedCollectionView(new List<T>());//empty collection
}
public DynamicCollection(IEnumerable<T>collection)
{
Collection = new PagedCollectionView(collection);
}
public DynamicCollection(Del delegateQuery)
{
Query = delegateQuery;
}
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
return Collection.GetEnumerator();
}
#endregion IEnumerable Members
#region INotifyCollectionChanged Members
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler handler = CollectionChanged;
if (handler != null)
{
CollectionChanged(this, e);
}
}
#endregion INotifyCollectionChanged Members
}