0

如何确保始终对 ObservableCollection 进行排序?


WPF

我的 ViewModel 中有一个 ObservableCollection:

public ObservableCollection<MyViewModel> Rows { get; private set; }

我在网格中有一个下拉菜单,其中显示Name属性MyViewModel(这是DevExpress):

<dxg:GridColumn x:Name="PortwareName" Header="Destination Id" FieldName="Rows" MinWidth="200">
    <dxg:GridColumn.EditSettings>
       <dxe:ComboBoxEditSettings AutoComplete="True" 
                                ValueMember="Name" 
                                DisplayMember="Name" 
                                FilterCondition="Contains"
                                IncrementalFiltering="True"
                                ImmediatePopup="True" 
                                ItemsSource="{Binding Path=Rows}" />
    </dxg:GridColumn.EditSettings>
</dxg:GridColumn>

免责声明

我与 DevExpress 无关(Infragistics 也很棒),下拉菜单也可以使用通用 WPF 控件。

4

2 回答 2

1

ICollectionView在集合上添加一个包装器,然后将 XAML 中的属性更改为ItemsSource={Binding Path=RowsSorted}"

private ICollectionView _rowsSorted;

public ICollectionView RowsSorted
{
  get
  {
    if (_rowsSorted == null)
    {
      _rowsSorted = CollectionViewSource.GetDefaultView(Rows);
      _rowsSorted.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
    }
    return _rowsSorted;
  }
}

该集合将按类中的属性进行Name排序Rows

其他解决方案?

还有许多其他解决方案,其中大多数涉及特殊的可观察集合,无论添加什么,它们都会保持排序。但是,我发现添加这个“包装器”集合很有效,并且没有隐藏的角落案例。

为什么添加包装器只不过是混淆......

这是另一个解决方案。但是,您会发现包装器代码并没有增加太多价值:

  • 它并没有真正减少打字量。
  • 它很好地掩盖了实际发生的事情。
  • 它是专有的,因此其他人无法轻松阅读您的代码。
  • 不建议。

编码:

/// <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;
        }
    }
}
于 2016-06-16T15:44:11.993 回答
1
public iEnumerable<MyViewModel> SortedObservableCollection 
{
    get { 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>
于 2016-06-16T16:24:23.140 回答