【问题标题】:Sorting a combobox purely in XAML纯粹在 XAML 中对组合框进行排序
【发布时间】:2010-02-16 17:00:29
【问题描述】:

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

我有一个数据绑定到 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 指定名称并直接操作它,这通常会破坏绑定。

感谢您的帮助!

【问题讨论】:

    标签: wpf xaml sorting combobox


    【解决方案1】:

    您可以使用 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();
        }
    }
    

    【讨论】:

    • 酷,这绝对是可能的。我刚刚找到这篇文章bea.stollnitz.com/blog/?p=17,所以很高兴听到 CollectionViewSource 是我可能的解决方案。但是,我认为这无需刷新即可工作...感谢您的提示!
    • 谁能解释 ItemsSource="{StaticResource cvs}" 和 ItemsSource="{Binding Source={StaticResource cvs}}" 之间的区别?我一直认为 StaticResource 暗示有一个绑定,所以我只是有一个概念上的障碍要跳过,为什么需要指定 Binding 而不是隐式的?
    猜你喜欢
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多