none
为什么我在自定义控件上放了一个datagridview,设置一个datagirdviewcomboboxcolumn列,设置了datasource后在窗体上使用时却没有数据呢? RRS feed

  • 问题

  • 下面是我写的代码
    uCtrlTest.cs
    =====================
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.Text;
    using System.Windows.Forms;

    namespace DGVCellPaintingTest
    {  
        public partial class uCtrlTest : UserControl
        {
            DataTable srcTable = null;
            public uCtrlTest()
            {
                InitializeComponent();

                this.Load += new EventHandler(uCtrlTest_Load);
            }

            void uCtrlTest_Load(object sender, EventArgs e)
            {
                srcTable = new DataTable();
                srcTable.Columns.Add("colId", typeof(string));
                srcTable.Columns.Add("colName", typeof(string));
                srcTable.Columns.Add("colSex", typeof(string));
                srcTable.Columns.Add("colAge", typeof(string));
                srcTable.Columns.Add("colAddress", typeof(string));
                srcTable.Columns.Add("colBirthday", typeof(string));
                DataRow nr = srcTable.NewRow();
                nr["colId"] = 10;
                nr["colName"] = "Jim";
                nr["colSex"] = "M";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);

                nr = srcTable.NewRow();
                nr["colId"] = 11;
                nr["colName"] = "Tom";
                nr["colSex"] = "M";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);

                nr = srcTable.NewRow();
                nr["colId"] = 12;
                nr["colName"] = "Marry";
                nr["colSex"] = "F";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);

                dataGridView1.RowCount = 6;
                dataGridView1.ColumnCount = 6;
                dataGridView1.AutoGenerateColumns = false;
                dataGridView1.Columns[0].DataPropertyName = "colId";
                dataGridView1.Columns[1].DataPropertyName = "colName";
                dataGridView1.Columns[2].DataPropertyName = "colSex";
                dataGridView1.Columns[3].DataPropertyName = "colAge";
                dataGridView1.Columns[4].DataPropertyName = "colAddress";
                dataGridView1.Columns[5].DataPropertyName = "colBirthday";

                DataGridViewComboBoxColumn cboCol = new DataGridViewComboBoxColumn();
                //cboCol.DataSource = cboTable;
                cboCol.DisplayMember = "SexDesc";
                cboCol.ValueMember = "SexId";
                dataGridView1.Columns.Add(cboCol);

                dataGridView1.DataSource = srcTable;

                setCboCellDataSource();

            }
            void setCboCellDataSource()
            {
                DataTable cboTable = null;
                cboTable = new DataTable();
                cboTable.Columns.Add("SexId", typeof(string));
                cboTable.Columns.Add("SexDesc", typeof(string));
                DataRow nr = cboTable.NewRow();
                nr["SexId"] = 1;
                nr["SexDesc"] = "Male";
                cboTable.Rows.Add(nr);

                nr = cboTable.NewRow();
                nr["SexId"] = 2;
                nr["SexDesc"] = "Female";
                cboTable.Rows.Add(nr);

                DataGridViewComboBoxCell tmpCboCell = null;
                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {
                    tmpCboCell = dataGridView1.Rows[i].Cells[6] as DataGridViewComboBoxCell;
                    if (tmpCboCell != null)
                    {
                        nr = cboTable.NewRow();
                        nr["SexDesc"] = "Unknown" + i.ToString();
                        nr["SexId"] = i;
                        cboTable.Rows.Add(nr);

                        tmpCboCell.DataSource = cboTable;
                        tmpCboCell.DisplayMember = "SexDesc";
                        tmpCboCell.ValueMember = "SexId";
                    }
                }
            }
        }
    }
    =======================
    Form1.cs
    ==============================
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;

    namespace DGVCellPaintingTest
    {
        public partial class Form1 : Form
        {
            DataTable srcTable = null;
           
            public Form1()
            {
                InitializeComponent();
                this.Load += new EventHandler(Form1_Load);
            }

            void Form1_Load(object sender, EventArgs e)
            {
                srcTable = new DataTable();
                srcTable.Columns.Add("colId", typeof(string));
                srcTable.Columns.Add("colName", typeof(string));
                srcTable.Columns.Add("colSex", typeof(string));
                srcTable.Columns.Add("colAge", typeof(string));
                srcTable.Columns.Add("colAddress", typeof(string));
                srcTable.Columns.Add("colBirthday", typeof(string));
                DataRow nr = srcTable.NewRow();
                nr["colId"] = 10;
                nr["colName"] = "Jim";
                nr["colSex"] = "M";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);

                nr = srcTable.NewRow();
                nr["colId"] = 11;
                nr["colName"] = "Tom";
                nr["colSex"] = "M";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);

                nr = srcTable.NewRow();
                nr["colId"] = 12;
                nr["colName"] = "Marry";
                nr["colSex"] = "F";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);

                dataGridView1.RowCount = 6;
                dataGridView1.ColumnCount = 6;
                dataGridView1.AutoGenerateColumns = false;
                dataGridView1.Columns[0].DataPropertyName = "colId";
                dataGridView1.Columns[1].DataPropertyName = "colName";
                dataGridView1.Columns[2].DataPropertyName = "colSex";
                dataGridView1.Columns[3].DataPropertyName = "colAge";
                dataGridView1.Columns[4].DataPropertyName = "colAddress";
                dataGridView1.Columns[5].DataPropertyName = "colBirthday";

                DataGridViewComboBoxColumn cboCol = new DataGridViewComboBoxColumn();
                //cboCol.DataSource = cboTable;
                cboCol.DisplayMember = "SexDesc";
                cboCol.ValueMember = "SexId";
                dataGridView1.Columns.Add(cboCol);

                dataGridView1.DataSource = srcTable;

                setCboCellDataSource();
                dataGridView1.Columns[0].ReadOnly = true;
                dataGridView1.Columns[1].Frozen = true;

                this.Controls.Add(new uCtrlTest());
            }

            void setCboCellDataSource()
            {
                DataTable cboTable = null;
                cboTable = new DataTable();
                cboTable.Columns.Add("SexId", typeof(string));
                cboTable.Columns.Add("SexDesc", typeof(string));
                DataRow nr = cboTable.NewRow();
                nr["SexId"] = 1;
                nr["SexDesc"] = "Male";
                cboTable.Rows.Add(nr);

                nr = cboTable.NewRow();
                nr["SexId"] = 2;
                nr["SexDesc"] = "Female";
                cboTable.Rows.Add(nr);

                DataGridViewComboBoxCell tmpCboCell = null;
                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {
                    tmpCboCell = dataGridView1.Rows[i].Cells[6] as DataGridViewComboBoxCell;
                    if (tmpCboCell != null)
                    {
                        nr = cboTable.NewRow();
                        nr["SexDesc"] = "Unknown" + i.ToString();
                        nr["SexId"] = i;
                        cboTable.Rows.Add(nr);

                        tmpCboCell.DataSource = cboTable;
                        tmpCboCell.DisplayMember = "SexDesc";
                        tmpCboCell.ValueMember = "SexId";
                    }
                }
            }

                }
    }
    =============================
    我把combobox的datasource设置放在form1的load过程,就可以,始终想不明白是怎么回事???

    2009年12月6日 13:12

答案

  • 你好!

    使用 DataBindingComplete 事件设置 Combobox 的数据源。正确的 UserControl 代码如下:


    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication2
    {
        public partial class UserControl1 : UserControl
        {
            DataTable srcTable = null;
    
            public UserControl1()
            {
                InitializeComponent();
            }
    
            private void UserControl1_Load(object sender, EventArgs e)
            {
                srcTable = new DataTable();
                srcTable.Columns.Add("colId", typeof(string));
                srcTable.Columns.Add("colName", typeof(string));
                srcTable.Columns.Add("colSex", typeof(string));
                srcTable.Columns.Add("colAge", typeof(string));
                srcTable.Columns.Add("colAddress", typeof(string));
                srcTable.Columns.Add("colBirthday", typeof(string));
                DataRow nr = srcTable.NewRow();
                nr["colId"] = 10;
                nr["colName"] = "Jim";
                nr["colSex"] = "M";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);
    
                nr = srcTable.NewRow();
                nr["colId"] = 11;
                nr["colName"] = "Tom";
                nr["colSex"] = "M";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);
    
                nr = srcTable.NewRow();
                nr["colId"] = 12;
                nr["colName"] = "Marry";
                nr["colSex"] = "F";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);
    
                dataGridView1.RowCount = 6;
                dataGridView1.ColumnCount = 6;
                dataGridView1.AutoGenerateColumns = false;
                dataGridView1.Columns[0].DataPropertyName = "colId";
                dataGridView1.Columns[1].DataPropertyName = "colName";
                dataGridView1.Columns[2].DataPropertyName = "colSex";
                dataGridView1.Columns[3].DataPropertyName = "colAge";
                dataGridView1.Columns[4].DataPropertyName = "colAddress";
                dataGridView1.Columns[5].DataPropertyName = "colBirthday";
    
                DataGridViewComboBoxColumn cboCol = new DataGridViewComboBoxColumn();
                //cboCol.DataSource = cboTable;
                //cboCol.DisplayMember = "SexDesc";
                //cboCol.ValueMember = "SexId";
                dataGridView1.Columns.Add(cboCol);
    
                dataGridView1.DataSource = srcTable;
                dataGridView1.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(dataGridView1_DataBindingComplete);
            }
    
            void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
            {
                setCboCellDataSource();
            }
    
            DataTable cboTable = null;
    
            void setCboCellDataSource()
            {
                DataTable cboTable = null;
                cboTable = new DataTable();
                cboTable.Columns.Add("SexId", typeof(string));
                cboTable.Columns.Add("SexDesc", typeof(string));
                DataRow nr = cboTable.NewRow();
                nr["SexId"] = 1;
                nr["SexDesc"] = "Male";
                cboTable.Rows.Add(nr);
    
                nr = cboTable.NewRow();
                nr["SexId"] = 2;
                nr["SexDesc"] = "Female";
                cboTable.Rows.Add(nr);
    
                DataGridViewComboBoxCell tmpCboCell = null;
                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {
                    tmpCboCell = dataGridView1.Rows[i].Cells[6] as DataGridViewComboBoxCell;
                    if (tmpCboCell != null)
                    {
                        nr = cboTable.NewRow();
                        nr["SexDesc"] = "Unknown" + i.ToString();
                        nr["SexId"] = i;
                        cboTable.Rows.Add(nr);
    
                        tmpCboCell.DataSource = cboTable;
                        tmpCboCell.DisplayMember = "SexDesc";
                        tmpCboCell.ValueMember = "SexId";
                    }
                }
    
    
            }
        }
    }
    


    知识改变命运,奋斗成就人生!
    2009年12月7日 1:36
    版主
  • 你好!

    DataBindingComplete 事件是在数据绑定完成后触发的。而控件是被加入到界面中才会被绑定。所以你原始的代码 setCboCellDataSource 方法是运行在绑定之前,问题也是由此造成。


    知识改变命运,奋斗成就人生!
    • 已标记为答案 YiChun Chen 2009年12月8日 10:22
    2009年12月8日 1:16
    版主

全部回复

  • 你好!

    使用 DataBindingComplete 事件设置 Combobox 的数据源。正确的 UserControl 代码如下:


    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication2
    {
        public partial class UserControl1 : UserControl
        {
            DataTable srcTable = null;
    
            public UserControl1()
            {
                InitializeComponent();
            }
    
            private void UserControl1_Load(object sender, EventArgs e)
            {
                srcTable = new DataTable();
                srcTable.Columns.Add("colId", typeof(string));
                srcTable.Columns.Add("colName", typeof(string));
                srcTable.Columns.Add("colSex", typeof(string));
                srcTable.Columns.Add("colAge", typeof(string));
                srcTable.Columns.Add("colAddress", typeof(string));
                srcTable.Columns.Add("colBirthday", typeof(string));
                DataRow nr = srcTable.NewRow();
                nr["colId"] = 10;
                nr["colName"] = "Jim";
                nr["colSex"] = "M";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);
    
                nr = srcTable.NewRow();
                nr["colId"] = 11;
                nr["colName"] = "Tom";
                nr["colSex"] = "M";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);
    
                nr = srcTable.NewRow();
                nr["colId"] = 12;
                nr["colName"] = "Marry";
                nr["colSex"] = "F";
                nr["colAge"] = 12;
                nr["colAddress"] = "Road 12";
                nr["colBirthday"] = "2005-10-12";
                srcTable.Rows.Add(nr);
    
                dataGridView1.RowCount = 6;
                dataGridView1.ColumnCount = 6;
                dataGridView1.AutoGenerateColumns = false;
                dataGridView1.Columns[0].DataPropertyName = "colId";
                dataGridView1.Columns[1].DataPropertyName = "colName";
                dataGridView1.Columns[2].DataPropertyName = "colSex";
                dataGridView1.Columns[3].DataPropertyName = "colAge";
                dataGridView1.Columns[4].DataPropertyName = "colAddress";
                dataGridView1.Columns[5].DataPropertyName = "colBirthday";
    
                DataGridViewComboBoxColumn cboCol = new DataGridViewComboBoxColumn();
                //cboCol.DataSource = cboTable;
                //cboCol.DisplayMember = "SexDesc";
                //cboCol.ValueMember = "SexId";
                dataGridView1.Columns.Add(cboCol);
    
                dataGridView1.DataSource = srcTable;
                dataGridView1.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(dataGridView1_DataBindingComplete);
            }
    
            void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
            {
                setCboCellDataSource();
            }
    
            DataTable cboTable = null;
    
            void setCboCellDataSource()
            {
                DataTable cboTable = null;
                cboTable = new DataTable();
                cboTable.Columns.Add("SexId", typeof(string));
                cboTable.Columns.Add("SexDesc", typeof(string));
                DataRow nr = cboTable.NewRow();
                nr["SexId"] = 1;
                nr["SexDesc"] = "Male";
                cboTable.Rows.Add(nr);
    
                nr = cboTable.NewRow();
                nr["SexId"] = 2;
                nr["SexDesc"] = "Female";
                cboTable.Rows.Add(nr);
    
                DataGridViewComboBoxCell tmpCboCell = null;
                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {
                    tmpCboCell = dataGridView1.Rows[i].Cells[6] as DataGridViewComboBoxCell;
                    if (tmpCboCell != null)
                    {
                        nr = cboTable.NewRow();
                        nr["SexDesc"] = "Unknown" + i.ToString();
                        nr["SexId"] = i;
                        cboTable.Rows.Add(nr);
    
                        tmpCboCell.DataSource = cboTable;
                        tmpCboCell.DisplayMember = "SexDesc";
                        tmpCboCell.ValueMember = "SexId";
                    }
                }
    
    
            }
        }
    }
    


    知识改变命运,奋斗成就人生!
    2009年12月7日 1:36
    版主
  • 非常感谢你的回答,我验证过确实可以;
    我还想问一下为什么我之前的写法不可以,原因是什么?
    再有用DataBindingComplete事件,在设置datasource后会被执行过很多次,这样每执行一次就会执行for循环,想问下,DataBindingComplete什么时候会被执行,如何能够避免这样重复的循环?
    2009年12月7日 12:00
  • 你好!

    DataBindingComplete 事件是在数据绑定完成后触发的。而控件是被加入到界面中才会被绑定。所以你原始的代码 setCboCellDataSource 方法是运行在绑定之前,问题也是由此造成。


    知识改变命运,奋斗成就人生!
    • 已标记为答案 YiChun Chen 2009年12月8日 10:22
    2009年12月8日 1:16
    版主