当前位置:  开发笔记 > 编程语言 > 正文

C#为什么不能设置动态创建的组合框的selectedValue?

如何解决《C#为什么不能设置动态创建的组合框的selectedValue?》经验,为你挑选了1个好方法。

我在类中创建了一个组合框,并希望为该组合框设置选定的值.但是当我这样做时,selectedValue保持为null,当我尝试设置selectedIndex时,我得到一个ArgumentOutOfRangeException.

码:

public Control GenerateList(Question question)
{
    // Clear the local givenAnswer collection
    _givenAnswer.Clear();

    // Get a list with answer possibilities
    List answers = question.GetAnswerSort();

    // Get a collection of given answers
    Collection givenAnswers = question.GetGivenAnswers();

    _givenAnswer = givenAnswers;

    ComboBox cmb = new ComboBox();
    cmb.Name = "cmb";
    cmb.DisplayMember = "Answer";
    cmb.ValueMember = "Id";
    cmb.DataSource = answers;
    cmb.Dock = DockStyle.Top;

    // Check an answer is given to the question
    if (givenAnswers != null && givenAnswers.Count > 0)
    {
        cmb.Tag = givenAnswers[0].AnswerId;
        cmb.SelectedValue = givenAnswers[0].AnswerId; // answerId = 55, but SelectedValue stays null
    }

    cmb.SelectedIndex = 1; // For testting. This will throw a ArgumentOutOfRangeException
    cmb.DropDownStyle = ComboBoxStyle.DropDownList;
    cmb.SelectedIndexChanged += new EventHandler(cmb_SelectedIndexChanged);

    return cmb;
}

我希望有人可以向我解释发生了什么,这样我就能理解为什么它不起作用.

这是一个完整的小程序,说明了我的问题.如您所见,它没有设置SelectedValue,它保持为null

namespace Dynamic_Create_Combo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            GenerateControls gc = new GenerateControls();
            Control c = gc.GenerateCombo();

            this.SuspendLayout();
            this.Controls.Add(c);
            this.ResumeLayout(true);
        }
    }

    public class GenerateControls
    {
        public Control GenerateCombo()
        {
            // Create datasource
            Collection cars = new Collection();
            Car c = new Car();
            c.Id = 1;
            c.Name = "Car one";
            cars.Add(c);

            Car c1 = new Car();
            c1.Id = 2;
            c1.Name = "Car two";
            cars.Add(c1);

            Car c2 = new Car();
            c2.Id = 2;
            c2.Name = "Car three";
            cars.Add(c2);

            ComboBox cmb = new ComboBox();
            cmb.DropDownStyle = ComboBoxStyle.DropDownList;
            cmb.DataSource = cars;
            cmb.DisplayMember = "Name";
            cmb.ValueMember = "Id";

            cmb.SelectedValue = 2;

            return cmb;
        }
    }

    public class Car
    {
        private int _id;
        private string _name;

        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        public string Name 
        {
            get { return _name; }
            set { _name = value; }
        }
    }
}

Jon Skeet.. 10

您已将值成员设置为"Id",但您尝试使用"AnswerId"作为选定值.

没有更多细节,很难说为什么设置SelectedIndex会抛出ArgumentOutOfRangeException- 也许组合框忽略了所有没有"Id"属性的值,因此没有给你任何值,所以选择索引1是不可能的?

编辑:好的,所以它看起来只是在它变得可见时才实际进行绑定 - 或者在过程的某个阶段.我已经尝试了一些方法来加速这一点,但它们似乎没有帮助.您可以做的是推迟您的选择:

EventHandler visibleChangedHandler = null;
visibleChangedHandler = delegate {
    cmb.SelectedIndex = 2;
    cmb.VisibleChanged -= visibleChangedHandler; // Only do this once!
};
cmb.VisibleChanged += visibleChangedHandler;

这是一个丑陋的解决方法,但它至少应该帮助你暂时开始.



1> Jon Skeet..:

您已将值成员设置为"Id",但您尝试使用"AnswerId"作为选定值.

没有更多细节,很难说为什么设置SelectedIndex会抛出ArgumentOutOfRangeException- 也许组合框忽略了所有没有"Id"属性的值,因此没有给你任何值,所以选择索引1是不可能的?

编辑:好的,所以它看起来只是在它变得可见时才实际进行绑定 - 或者在过程的某个阶段.我已经尝试了一些方法来加速这一点,但它们似乎没有帮助.您可以做的是推迟您的选择:

EventHandler visibleChangedHandler = null;
visibleChangedHandler = delegate {
    cmb.SelectedIndex = 2;
    cmb.VisibleChanged -= visibleChangedHandler; // Only do this once!
};
cmb.VisibleChanged += visibleChangedHandler;

这是一个丑陋的解决方法,但它至少应该帮助你暂时开始.

推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有