Wpf 如何从ObservableCollection创建已排序下拉列表?
如何确保ObservableCollection始终被排序Wpf 如何从ObservableCollection创建已排序下拉列表?,wpf,mvvm,observablecollection,dropdown,devexpress-wpf,Wpf,Mvvm,Observablecollection,Dropdown,Devexpress Wpf,如何确保ObservableCollection始终被排序 WPF 我的ViewModel中有一个可观察的集合: public ObservableCollection<MyViewModel> Rows { get; private set; } 免责声明 我与DevExpress没有任何关系(Infragistics也很好),下拉列表也可以使用通用的WPF控件。在集合上添加一个ICollectionView包装,然后将XAML中的属性更改为ItemsSource={Bindi
WPF 我的ViewModel中有一个可观察的集合:
public ObservableCollection<MyViewModel> Rows { get; private set; }
免责声明
我与DevExpress没有任何关系(Infragistics也很好),下拉列表也可以使用通用的WPF控件。在集合上添加一个
ICollectionView
包装,然后将XAML中的属性更改为ItemsSource={Binding Path=Rowstorted}
:
集合将按行
类中的属性名称
排序
其他解决方案?
还有许多其他的解决方案,大多数都涉及特殊的可观察集合,无论添加了什么,这些集合都会保持排序。但是,我发现添加这个“包装器”集合很有效,并且没有隐藏的角落案例
为什么添加包装器只会造成混淆。。。
下面是另一个解决方案。但是,您会发现包装器代码没有增加多少价值:
- 它实际上并没有减少多少打字量
- 它很好地掩盖了实际发生的事情
- 它是专有的,因此其他人无法轻松阅读您的代码
- 不推荐
/// <summary>
/// Intent: Wrapper over a sorted collection.
/// </summary>
/// <demo>
/*
// Demo of how to wrap a sorted ObservableCollection over an existing one.
private SortedObservableCollection<MyViewModel> _rowsSorted;
public ICollectionView PortwareBrokerDropdownListSorted
{
get
{
if (_rowsSorted == null)
{
// Rows is the original observable collection.
_rowsSorted = new SortedObservableCollection<MyViewModel>(Rows, "Name");
}
return _rowsSorted.Value;
}
}
*/
/// </demo>
public class SortedObservableCollection<T>
{
private readonly ObservableCollectionSmart<T> _sourceCollection;
private readonly string _fieldName;
public SortedObservableCollection(ObservableCollectionSmart<T> sourceCollection, string fieldName)
{
_sourceCollection = sourceCollection;
_fieldName = fieldName;
}
private ICollectionView _rowsSorted;
public ICollectionView Value
{
get
{
if (_rowsSorted == null)
{
_rowsSorted = CollectionViewSource.GetDefaultView(_sourceCollection);
_rowsSorted.SortDescriptions.Add(new SortDescription(_fieldName, ListSortDirection.Ascending));
}
return _rowsSorted;
}
}
}
//
///意图:已排序集合上的包装器。
///
///
/*
//演示如何将已排序的ObservableCollection包装到现有集合上。
私人分类服务收集;
public ICollectionView PortwareBrokerDropDownList已排序
{
得到
{
如果(_rowsorted==null)
{
//行是原始的可观察集合。
_RowsOrted=新的SortedObjectCollection(行,“名称”);
}
返回_rowstorted.Value;
}
}
*/
///
公共类可服务集合
{
私有只读ObservableCollectionSmart\u sourceCollection;
私有只读字符串_fieldName;
公共SortedObjectableCollection(ObservableCollectionSmart sourceCollection,字符串字段名)
{
_sourceCollection=sourceCollection;
_fieldName=fieldName;
}
私人ICollectionView _-rowsted;
公共ICollectionView值
{
得到
{
如果(_rowsorted==null)
{
_RowsOrted=CollectionViewSource.GetDefaultView(_sourceCollection);
_rowsorted.SortDescriptions.Add(新的SortDescription(_fieldName,ListSortDirection.升序));
}
返回(已分配);;
}
}
}
在集合上添加一个ICollectionView
包装,然后将XAML中的属性更改为ItemsSource={Binding Path=rowsorted}“
:
集合将按行
类中的属性名称
排序
其他解决方案?
还有许多其他的解决方案,其中大多数涉及特殊的可观察集合,这些集合无论添加了什么都保持排序。然而,我发现添加这个“包装器”集合非常有效,并且没有隐藏的角落案例
为什么添加包装器只会造成混淆。。。
这是另一个解决方案。但是,您会发现包装器代码并没有增加多少价值:
- 它实际上并没有减少多少打字量
- 它很好地掩盖了实际发生的事情李>
- 它是专有的,因此其他人无法轻松阅读您的代码李>
- 不推荐
/// <summary>
/// Intent: Wrapper over a sorted collection.
/// </summary>
/// <demo>
/*
// Demo of how to wrap a sorted ObservableCollection over an existing one.
private SortedObservableCollection<MyViewModel> _rowsSorted;
public ICollectionView PortwareBrokerDropdownListSorted
{
get
{
if (_rowsSorted == null)
{
// Rows is the original observable collection.
_rowsSorted = new SortedObservableCollection<MyViewModel>(Rows, "Name");
}
return _rowsSorted.Value;
}
}
*/
/// </demo>
public class SortedObservableCollection<T>
{
private readonly ObservableCollectionSmart<T> _sourceCollection;
private readonly string _fieldName;
public SortedObservableCollection(ObservableCollectionSmart<T> sourceCollection, string fieldName)
{
_sourceCollection = sourceCollection;
_fieldName = fieldName;
}
private ICollectionView _rowsSorted;
public ICollectionView Value
{
get
{
if (_rowsSorted == null)
{
_rowsSorted = CollectionViewSource.GetDefaultView(_sourceCollection);
_rowsSorted.SortDescriptions.Add(new SortDescription(_fieldName, ListSortDirection.Ascending));
}
return _rowsSorted;
}
}
}
//
///意图:已排序集合上的包装器。
///
///
/*
//演示如何将已排序的ObservableCollection包装到现有集合上。
私人分类服务收集;
public ICollectionView PortwareBrokerDropDownList已排序
{
得到
{
如果(_rowsorted==null)
{
//行是原始的可观察集合。
_RowsOrted=新的SortedObjectCollection(行,“名称”);
}
返回_rowstorted.Value;
}
}
*/
///
公共类可服务集合
{
私有只读ObservableCollectionSmart\u sourceCollection;
私有只读字符串_fieldName;
公共SortedObjectableCollection(ObservableCollectionSmart sourceCollection,字符串字段名)
{
_sourceCollection=sourceCollection;
_fieldName=fieldName;
}
私人ICollectionView _-rowsted;
公共ICollectionView值
{
得到
{
如果(_rowsorted==null)
{
_RowsOrted=CollectionViewSource.GetDefaultView(_sourceCollection);
_rowsorted.SortDescriptions.Add(新的SortDescription(_fieldName,ListSortDirection.升序));
}
返回(已分配);;
}
}
}
公共iEnumerable SortedoServable集合
{
获取{return Rows.OrderBy(x=>x.Name);}
}
您可以在XAML中执行CollectionViewSource
<Window.Resources>
<src:Places x:Key="places"/>
<CollectionViewSource Source="{StaticResource places}" x:Key="cvs" IsLiveSorting="True">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="CityName"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
公共iEnumerable SortedoServable集合
{
获取{return Rows.OrderBy(x=>x.Name);}
}
您可以在XAML中执行CollectionViewSource
<Window.Resources>
<src:Places x:Key="places"/>
<CollectionViewSource Source="{StaticResource places}" x:Key="cvs" IsLiveSorting="True">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="CityName"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
你为什么要问和回答自己的问题?@RickS对于那些想分享知识的人来说,这是特别允许和鼓励的。当然,这个问题必须是一个有效的问题,而这个问题是。OP在这里介绍了许多分类收集的方法,这对遇到同样情况的人很有帮助。你为什么要问和回答你自己的问题?@RickS这是特别允许和鼓励那些想要分享知识的人的。当然,这个问题必须是一个有效的问题,而这个问题是。OP here提供了许多对集合进行排序的方法,这对遇到相同情况的人很有帮助。这不起作用,因为如果行发生更改,UI将不知道刷新。@Will OK。您确定私有ICollectionView\u rowso
<Window.Resources>
<src:Places x:Key="places"/>
<CollectionViewSource Source="{StaticResource places}" x:Key="cvs" IsLiveSorting="True">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="CityName"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>