看传智博客的一个很简单的例子,根据“省”检索“市”,向combobox插入数据时,将数据库内的AreaID, AreaName列取出来,分别做为实际值和显示列。声明一个类:
 private class Sheng
        {
            public int AreaId { get; set; }
            public string AreaName { get; set; }
        }然后:
       private void FrmCombobox_Load(object sender, EventArgs e)
        {
            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnStr"].ToString()))
            {
                conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "SELECT   AreaID, AreaName, RootID FROM common_Area WHERE RootID = 0";
                    using (SqlDataReader sdr = cmd.ExecuteReader())
                    {
                        cbSheng.Items.Clear();
                        cbSheng.DisplayMember = "AreaName";                        Sheng shengItem = new Sheng();
                        int indexAreaID = sdr.GetOrdinal("AreaID");
                        int indexAreaName = sdr.GetOrdinal("AreaName");
                        while (sdr.Read())
                        {
                            shengItem.AreaId = sdr.GetInt32(indexAreaID);
                            shengItem.AreaName = sdr.GetString(indexAreaName);
                            cbSheng.Items.Add(shengItem);
                            //MessageBox.Show(sdr.GetInt32(indexAreaID) + " " + sdr.GetString(indexAreaName));
                        }
                    }
                }
            }
        }这两步都没问题,值都正确取出而且插入到cbSheng中去了
下面我要在cbSheng的SelectedIndexChanged事件中得到选中的AreaID和AreaName,这时候真奇怪,取出来的值死活就是最后一行,我实在是看不出这么简单的代码里会有什么问题,请大家指教
        private void cbSheng_SelectedIndexChanged(object sender, EventArgs e)
        {
            Sheng shengItem = new Sheng();
            shengItem = (Sheng)cbSheng.SelectedItem;
            MessageBox.Show(cbSheng.SelectedIndex + " - " + shengItem.AreaId + shengItem.AreaName);
           //明明cbSheng.SelectedIndex 的值已经改变,但SelectedItem的值总是最后一行
        }
我刚转而学c#,在网上查来查去也没找到类似的问题,谢谢大家。

解决方案 »

  1.   

    奇怪,照着你代码写了一次,没有问题呢,你看看我的代码吧,和你基本一样,但是运行正常哈
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.SqlClient;namespace WindowsFormsApplication3
    {
        class Product
        {
            public int ID { get; set; }
            public string Name { get; set; }
        }
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
                this.comboBox1.Items.Clear();
                using (SqlConnection conn = new SqlConnection("server=(local);integrated security=SSPI;database=NorthWind"))
                {
                    SqlCommand com = new SqlCommand();
                    com.CommandText = "select * from products";
                    com.Connection = conn;
                    conn.Open();
                    this.comboBox1.DisplayMember = "ID";
                    SqlDataReader reader = com.ExecuteReader();                while (reader.Read())
                    {
                        Product p = new Product();
                        p.ID = reader.GetInt32(0);
                        p.Name = reader.GetString(1);
                        this.comboBox1.Items.Add(p);
                    }
                }
                this.comboBox1.SelectedIndexChanged += new EventHandler(comboBox1_SelectedIndexChanged);
            }
            void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
                MessageBox.Show(((Product)this.comboBox1.SelectedItem).Name);
            }
        }
    }
      

  2.   

    忘了加 using (SqlDataReader reader = com.ExecuteReader())了哈,我们代码都是一样的,但是不知道为什么你的不行呢~
      

  3.   

    呵呵,对呀,我基本也是完全按照例程写的,在vs2005上写了,就这问题,怎么选都是最后一行,后来又在本本上的vs2010上再写一遍,还是总返回最后一行,真是怪哉。
    没人遇到过这问题吗?
      

  4.   

    ASP.net 的?
    把combobox的自动回发勾上
      

  5.   

    +1,如果是asp.net,把AutoPostBack设置成False
      

  6.   

    回4楼:不是,是winform的。回5楼:呵呵,十年如一日的用人家微软的盗版,是有点败人品,不过大家都是如此,你们怎么没这种事呀。
      

  7.   

    找到问题了,楼主,把Sheng shengItem = new Sheng();
    写到While循环里面就可以了,要不只有一个实例,后面的改变当然只会体现在那个实例上面。
      

  8.   

     Sheng shengItem = new Sheng();
                            int indexAreaID = sdr.GetOrdinal("AreaID");
                            int indexAreaName = sdr.GetOrdinal("AreaName");
                            while (sdr.Read())
                            {
                                shengItem.AreaId = sdr.GetInt32(indexAreaID);
                                shengItem.AreaName = sdr.GetString(indexAreaName);
                                cbSheng.Items.Add(shengItem);
                                //MessageBox.Show(sdr.GetInt32(indexAreaID) + " " + sdr.GetString(indexAreaName));
                            }问题出在这段里面了,你这每次往cbSheng.Items.Add(shengItem);
    添加,下一个对象会把上一个覆盖掉。你加一个断点调试一下,就明白了。
      

  9.   

    噢,还真是,我想想这是怎么回事。
    new一个新的实例放在循环外,对象是引用类型,这样每次传的只是这个实例的地址,下次循环时,虽然重新对那两个成员赋值,但改变的还是这个实例,所以,这个列表框的items[0] 到最后,一直都随着下一次重新赋值而改变,显示在界面上的值其实是显示完以后就被改变了。所以,最后取出来的值就是最后的赋值。
    呵呵,明白了,谢谢大家。