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;
  }
}

コレクションはNameRowsクラス内のプロパティによって並べ替えられます。

その他のソリューション?

他にも多くの解決策がありますが、それらのほとんどは、何が追加されてもソートされたままになる特別な観察可能なコレクションを含みます。ただし、この「ラッパー」コレクションを追加しても問題なく機能し、隠れたコーナー ケースがないことがわかりました。

ラッパーを追加しても難読化にすぎないのはなぜですか...

ここに別の解決策があります。ただし、ラッパー コードにはあまり価値がないことがわかります。

  • タイピングの量はそれほど減りません。
  • 実際に何が起こっているのかを覆い隠すのに適しています。
  • これはプロプライエタリであるため、他の人はあなたのコードを簡単に読むことができません。
  • 推奨されません。

コード:

/// <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 に答える