質問

Background: There are two combo boxes that differ only in the Sorted property. comboBox1 has the Sorted property set to true and comboBox2 has the Sorted property set to false. When attempting to reassign/reset the datasource property of these two combo boxes, comboBox1 displays no data and comboBox2 does. Why does the Sorted property prevent comboBox1 from displaying its' data properly?

All code included below:

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;
}
役に立ちましたか?

解決

Are you accidentally hiding an exception? According to MSDN you will receive an "ArgumentException" when "An attempt was made to sort a ComboBox that is attached to a data source."

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

他のヒント

Try to sort by sorting the list on setting the 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;

The problem is that You can not change data source of sorted combobox. Here is excerpt of the code of ComboBox control:

        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"));
        }
        ...
        ...
    }

In such case You should have received an InvalidOperationException. Why didn't You receive ? Here is the answer:

Implementation of DataSource property in ComboBox control redirects to its base class (ListControl) implementation:

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

And then in the base class's 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 = "";
                }
            }
        }
    }

Please, pay attention to the silent catch block. Since SetDataConnection calls OnDataSourceChanged then as far as my analysis is correct this is the reason. If I'm wrong, please correct me.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top