排序组合框并重新分配数据源

本文关键字:分配 数据源 新分配 组合 排序 | 更新日期: 2023-09-27 18:25:34

背景:有两个组合框,它们的区别仅在于Sorted属性。comboBox1的Sorted属性设置为true,comboBox2的Sorted特性设置为false。当试图重新分配/重置这两个组合框的数据源属性时,comboBox1不显示数据,comboBox2显示数据。为什么Sorted属性阻止comboBox1正确显示其"数据"?

下面包含的所有代码:

public partial class Form1 : Form
{
    private string[] a8BitGames = { "Metroid", "Zelda", "Phantasy Star", "SB:S&SEP" };
    private string[] a16BitGames = { "StarFox", "Link", "Final Fantasy", "Altered Beast" };
    private List<string> lSomeList = null;
    private List<string> lSomeOtherList = null;
    public Form1()
    {
        InitializeComponent();
        this.lSomeList = new List<string>(a8BitGames);
        this.lSomeOtherList = new List<string>(a16BitGames);
        this.comboBox1.DataSource = lSomeList;
        this.comboBox2.DataSource = lSomeOtherList;
    }
    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        this.IndexChanged(1);
    }
    private void IndexChanged(int comboBox)
    {
        this.comboBox1.DataSource = null;
        this.comboBox1.DataSource = a16BitGames;
        this.comboBox2.DataSource = null;
        this.comboBox2.DataSource = a8BitGames;
    }
    private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
    {
        this.IndexChanged(2);
    }
}
partial class Form1
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;
    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }
    #region Windows Form Designer generated code
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.comboBox1 = new System.Windows.Forms.ComboBox();
        this.comboBox2 = new System.Windows.Forms.ComboBox();
        this.SuspendLayout();
        // 
        // comboBox1
        // 
        this.comboBox1.FormattingEnabled = true;
        this.comboBox1.Location = new System.Drawing.Point(13, 13);
        this.comboBox1.Name = "comboBox1";
        this.comboBox1.Size = new System.Drawing.Size(121, 21);
        this.comboBox1.Sorted = true;
        this.comboBox1.TabIndex = 0;
        this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
        // 
        // comboBox2
        // 
        this.comboBox2.FormattingEnabled = true;
        this.comboBox2.Location = new System.Drawing.Point(13, 41);
        this.comboBox2.Name = "comboBox2";
        this.comboBox2.Size = new System.Drawing.Size(121, 21);
        this.comboBox2.TabIndex = 1;
        this.comboBox2.SelectedIndexChanged += new System.EventHandler(this.comboBox2_SelectedIndexChanged);
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(284, 262);
        this.Controls.Add(this.comboBox2);
        this.Controls.Add(this.comboBox1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);
    }
    #endregion
    private System.Windows.Forms.ComboBox comboBox1;
    private System.Windows.Forms.ComboBox comboBox2;
}

排序组合框并重新分配数据源

是否意外隐藏了异常?根据MSDN,当"试图对连接到数据源的组合框进行排序"时,您将收到一个"ArgumentException"

http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.sorted.aspx

尝试在设置DataSource 时对列表进行排序

 public List<string> A16Games
 {
    get { return this.a16BitGames.OrderBy(x => x).ToList(); }
 }
 public List<string> A8Games
 {
    get { return this.a8BitGames.OrderBy(x => x).ToList(); }
 }
 this.comboBox1.DataSource = this.A16Games;
 this.comboBox2.DataSource = this.A8Games;

问题是无法更改排序组合框的数据源。以下是ComboBox控件的代码摘录:

        protected override void OnDataSourceChanged(EventArgs e)
    {
        if ((this.Sorted && (this.DataSource != null)) && base.Created)
        {
            this.DataSource = null;
            throw new InvalidOperationException(System.Windows.Forms.SR.GetString("ComboBoxDataSourceWithSort"));
        }
        ...
        ...
    }

在这种情况下,您应该收到InvalidOperationException。为什么你没有收到?答案是:

ComboBox控件中DataSource属性的实现重定向到其基类(ListControl)实现:

        public object DataSource
    {
        get
        {
            return base.DataSource;
        }
        set
        {
            base.DataSource = value;
        }
    }

然后在基类的DataSource:中

        public object DataSource
    {
        [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        get
        {
            return this.dataSource;
        }
        set
        {
            if (((value != null) && !(value is IList)) && !(value is IListSource))
            {
                throw new ArgumentException(System.Windows.Forms.SR.GetString("BadDataSourceForComplexBinding"));
            }
            if (this.dataSource != value)
            {
                try
                {
                    this.SetDataConnection(value, this.displayMember, false);
                }
                catch
                {
                    this.DisplayMember = "";
                }
                if (value == null)
                {
                    this.DisplayMember = "";
                }
            }
        }
    }

请注意无声的catch块。由于SetDataConnection调用OnDataSourceChanged,所以就我的分析而言,这就是原因。如果我错了,请纠正我。