Wpf 如何从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

如何确保ObservableCollection始终被排序


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>