仅在XAML中对组合框进行排序

时间:2010-02-16 17:00:29

标签: wpf xaml sorting combobox

我很惊讶在此之前没有人问过这个问题......好吧,至少我在这里或其他地方找不到答案,实际上。

我有一个与ObservableCollection数据绑定的ComboBox。一切都很好,直到那些人想要内容排序。没问题 - 我最终改变了简单的属性:

public ObservableCollection<string> CandyNames { get; set; } // instantiated in constructor

这样的事情:

private ObservableCollection<string> _candy_names; // instantiated in constructor
public ObservableCollection<string> CandyNames
{
    get {
        _candy_names = new ObservableCollection<string>(_candy_names.OrderBy( i => i));
        return _candy_names;
    }
    set {
        _candy_names = value;
    }
}

这篇文章实际上是两个问题:

  1. 如何在XAML 中对字符串的简单组合框进行排序。我已经研究了这个,只能找到有关SortDescription类和this is the closest implementation I could find的信息,但它不适用于ComboBox。
  2. 一旦我在代码隐藏中实现了排序,我的数据绑定就被打破了;当我向ObservableCollection添加新项目时,ComboBox项目没有更新!我没有看到这是怎么发生的,因为我没有为我的ComboBox指定一个名称并直接操作它,这通常会破坏绑定。
  3. 感谢您的帮助!

1 个答案:

答案 0 :(得分:17)

您可以使用CollectionViewSource在XAML中进行排序,但是如果底层集合发生更改,则需要刷新它的视图。

XAML:

<Window x:Class="CBSortTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
    Height="300" Width="300">

    <Window.Resources>
        <CollectionViewSource Source="{Binding Path=CandyNames}" x:Key="cvs">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription />
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>

    </Window.Resources>
    <StackPanel>
        <ComboBox ItemsSource="{Binding Source={StaticResource cvs}}" />
        <Button Content="Add" Click="OnAdd" />
    </StackPanel>
</Window>

代码背后:

using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Data;

namespace CBSortTest
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            CandyNames = new ObservableCollection<string>();

            OnAdd(this, null);
            OnAdd(this, null);
            OnAdd(this, null);
            OnAdd(this, null);

            DataContext = this;

            CandyNames.CollectionChanged += 
                (sender, e) =>
                {
                    CollectionViewSource viewSource =
                        FindResource("cvs") as CollectionViewSource;
                    viewSource.View.Refresh();
                };
        }

        public ObservableCollection<string> CandyNames { get; set; }

        private void OnAdd(object sender, RoutedEventArgs e)
        {
            CandyNames.Add("Candy " + _random.Next(100));
        }

        private Random _random = new Random();
    }
}