none
WinForm中的DataGridViewComboBoxColumn RRS feed

  • 问题

  • 问题1:
    如何每行record绑定不同的数据源?
    比如我有个实体类
    public class A
    {
        public int Owner { get; set; }
        public String Letter { get; set; }
    }
    有个集合对象
    List<A> list = new List<A>();
    list.Add(new A() { Owner = 1, Letter = "A" });
    list.Add(new A() { Owner = 2, Letter = "D" });
    list.Add(new A() { Owner = 3, Letter = "G" });

    再有个DataGridView
    DataGridView dgv = new DataGridView();
    DataGridViewTextBoxColumn owner = new DataGridViewTextBoxColumn();
    owner.ReadOnly = true;
    owner.DataProperty = "Owner";
    DataGridViewComboBoxColumn letter = new DataGridViewComboBoxColumn();
    letter.ReadOnly = false;
    dgv.Columns.Add(owner);
    dgv.Columns.Add(letter);

    dgv.DataSource = list;

    设:Owner 1可以选择字母A,B,C
        Owner 2可以选择字母D,E,F
        Owner 3 可以选择字母G,H,I
    ComboBox列根据Owner的值做不同的数据源列表,该怎么写?
    我碰到问题的时候,下拉框的数据源是实体类,中有id和name属性,id是Guid类型,name是string类型.
    设置每行的Combox单元格的数据源会报错.
    不知道该怎么解决了..
    `
    问题2:
    把string用Convert.ChangeType()方法类型转换成SqlGuid时报错,我估计是因为SqlGuid没有实现IConvertible接口的原因吧,检查过字符串的格式没有问题.
    有没有类型转换的方法是可以支持很多种方法的.
    因为我在程序中用的反射,GetProperty()得到属性后SetValue(),
    如上的情况我需要先判断PropertyType是否为SqlGuid,如果是的话,就用SqlGuid.Parse()
    否,才能用Convert.ChangeType()


    有人说,充满技术的生活枯燥无味.. 我笑他们不懂.因为只有技术才能充实生活.. 学习就像生活,都需要善于总结,才能发现问题,取得进步.. 生活中充满了数学算式与结构,只要我们善于观察和思考..
    2009年6月16日 11:25

答案

  • 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;
    
    namespace X.WinFormsApp
    {
        public partial class X200906170939 : Form
        {
            private DataSet fEmployee;
            public DataSet Employee
            {
                get
                {
                    if (fEmployee == null)
                    {
                        fEmployee = new DataSet();
                        fEmployee.Tables.Add(new DataTable("Employee"));
    
                        fEmployee.Tables[0].Columns.Add(new DataColumn("EmployeeKey", typeof(Int32)));
                        fEmployee.Tables[0].Columns.Add(new DataColumn("DepartmentKey", typeof(Int32)));
                        fEmployee.Tables[0].Columns.Add(new DataColumn("Name", typeof(String)));
                        fEmployee.Tables[0].Columns.Add(new DataColumn("ModifyDate", typeof(DateTime)));
    
                        fEmployee.Tables[0].Rows.Add(new object[] { 1, 1, "John", DateTime.Now });
                        fEmployee.Tables[0].Rows.Add(new object[] { 2, 1, "Tomi", DateTime.Now });
                        fEmployee.Tables[0].Rows.Add(new object[] { 3, 2, "X.XY", DateTime.Now });
                        fEmployee.Tables[0].Rows.Add(new object[] { 4, 2, "Sam", DateTime.Now });
                        fEmployee.Tables[0].Rows.Add(new object[] { 5, 3, "Mary", DateTime.Now });
                        fEmployee.Tables[0].Rows.Add(new object[] { 6, 3, "Chirs", DateTime.Now });
                    }
    
                    return fEmployee;
                }
            }
    
            private DataSet fDepartment;
            public DataSet Department
            {
                get
                {
                    if (fDepartment == null)
                    {
                        fDepartment = new DataSet();
                        fDepartment.Tables.Add(new DataTable("Department"));
    
                        fDepartment.Tables[0].Columns.Add(new DataColumn("DepartmentKey", typeof(Int32)));
                        fDepartment.Tables[0].Columns.Add(new DataColumn("Name", typeof(String)));
    
                        fDepartment.Tables[0].Rows.Add(new object[] { 1, "A"});
                        fDepartment.Tables[0].Rows.Add(new object[] { 1, "B" });
                        fDepartment.Tables[0].Rows.Add(new object[] { 2, "C" });
                        fDepartment.Tables[0].Rows.Add(new object[] { 2, "D" });
                        fDepartment.Tables[0].Rows.Add(new object[] { 3, "E" });
                        fDepartment.Tables[0].Rows.Add(new object[] { 3, "F" });
                    }
    
                    return fDepartment;
                }
            }
    
            public X200906170939()
            {
                InitializeComponent();
                this.InitControls();
            }
    
            private void InitControls()
            {
                DataGridView fDataGridView = new DataGridView();
                fDataGridView.Dock = DockStyle.Fill;
                fDataGridView.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(fDataGridView_DataBindingComplete);
    
                fDataGridView.AutoGenerateColumns = false;
    
                DataGridViewColumn fColumn1 = new DataGridViewColumn(new DataGridViewTextBoxCell());
                fColumn1.HeaderText = "EmployeeKey";
                fColumn1.DataPropertyName = "EmployeeKey";
    
                DataGridViewColumn fColumn2 = new DataGridViewColumn(new DataGridViewTextBoxCell());
                fColumn2.HeaderText = "Name";
                fColumn2.DataPropertyName = "Name";
    
                DataGridViewColumn fColumn3 = new DataGridViewColumn(new DataGridViewComboBoxCell());
    
                fDataGridView.Columns.Add(fColumn1);
                fDataGridView.Columns.Add(fColumn2);
                fDataGridView.Columns.Add(fColumn3);
    
                fDataGridView.DataSource = this.Employee.Tables[0];
                this.Controls.Add(fDataGridView);
            }
    
            private void fDataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
            {
                DataGridView fDataGridView = (DataGridView) sender;
                foreach (DataGridViewRow fRow in fDataGridView.Rows)
                {
                    DataRowView fDataRowView = (DataRowView)fRow.DataBoundItem;
    
                    if (fDataRowView != null)
                    {
                        DataGridViewComboBoxCell fDataGridViewComboBoxCell = (DataGridViewComboBoxCell)fRow.Cells[2];
                        BindingSource fBindingSource = new BindingSource(this.Department, "Department");
                        fBindingSource.Filter = string.Format("DepartmentKey = {0}", (int)fDataRowView["DepartmentKey"]);
    
                        fDataGridViewComboBoxCell.DataSource = fBindingSource;
                        fDataGridViewComboBoxCell.DisplayMember = "Name";
                        fDataGridViewComboBoxCell.ValueMember = "DepartmentKey";
                    }
                }
            }
        }
    }
    

    知识改变命运,奋斗成就人生!
    2009年6月17日 2:22
    版主

全部回复

  • 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;
    
    namespace X.WinFormsApp
    {
        public partial class X200906170939 : Form
        {
            private DataSet fEmployee;
            public DataSet Employee
            {
                get
                {
                    if (fEmployee == null)
                    {
                        fEmployee = new DataSet();
                        fEmployee.Tables.Add(new DataTable("Employee"));
    
                        fEmployee.Tables[0].Columns.Add(new DataColumn("EmployeeKey", typeof(Int32)));
                        fEmployee.Tables[0].Columns.Add(new DataColumn("DepartmentKey", typeof(Int32)));
                        fEmployee.Tables[0].Columns.Add(new DataColumn("Name", typeof(String)));
                        fEmployee.Tables[0].Columns.Add(new DataColumn("ModifyDate", typeof(DateTime)));
    
                        fEmployee.Tables[0].Rows.Add(new object[] { 1, 1, "John", DateTime.Now });
                        fEmployee.Tables[0].Rows.Add(new object[] { 2, 1, "Tomi", DateTime.Now });
                        fEmployee.Tables[0].Rows.Add(new object[] { 3, 2, "X.XY", DateTime.Now });
                        fEmployee.Tables[0].Rows.Add(new object[] { 4, 2, "Sam", DateTime.Now });
                        fEmployee.Tables[0].Rows.Add(new object[] { 5, 3, "Mary", DateTime.Now });
                        fEmployee.Tables[0].Rows.Add(new object[] { 6, 3, "Chirs", DateTime.Now });
                    }
    
                    return fEmployee;
                }
            }
    
            private DataSet fDepartment;
            public DataSet Department
            {
                get
                {
                    if (fDepartment == null)
                    {
                        fDepartment = new DataSet();
                        fDepartment.Tables.Add(new DataTable("Department"));
    
                        fDepartment.Tables[0].Columns.Add(new DataColumn("DepartmentKey", typeof(Int32)));
                        fDepartment.Tables[0].Columns.Add(new DataColumn("Name", typeof(String)));
    
                        fDepartment.Tables[0].Rows.Add(new object[] { 1, "A"});
                        fDepartment.Tables[0].Rows.Add(new object[] { 1, "B" });
                        fDepartment.Tables[0].Rows.Add(new object[] { 2, "C" });
                        fDepartment.Tables[0].Rows.Add(new object[] { 2, "D" });
                        fDepartment.Tables[0].Rows.Add(new object[] { 3, "E" });
                        fDepartment.Tables[0].Rows.Add(new object[] { 3, "F" });
                    }
    
                    return fDepartment;
                }
            }
    
            public X200906170939()
            {
                InitializeComponent();
                this.InitControls();
            }
    
            private void InitControls()
            {
                DataGridView fDataGridView = new DataGridView();
                fDataGridView.Dock = DockStyle.Fill;
                fDataGridView.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(fDataGridView_DataBindingComplete);
    
                fDataGridView.AutoGenerateColumns = false;
    
                DataGridViewColumn fColumn1 = new DataGridViewColumn(new DataGridViewTextBoxCell());
                fColumn1.HeaderText = "EmployeeKey";
                fColumn1.DataPropertyName = "EmployeeKey";
    
                DataGridViewColumn fColumn2 = new DataGridViewColumn(new DataGridViewTextBoxCell());
                fColumn2.HeaderText = "Name";
                fColumn2.DataPropertyName = "Name";
    
                DataGridViewColumn fColumn3 = new DataGridViewColumn(new DataGridViewComboBoxCell());
    
                fDataGridView.Columns.Add(fColumn1);
                fDataGridView.Columns.Add(fColumn2);
                fDataGridView.Columns.Add(fColumn3);
    
                fDataGridView.DataSource = this.Employee.Tables[0];
                this.Controls.Add(fDataGridView);
            }
    
            private void fDataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
            {
                DataGridView fDataGridView = (DataGridView) sender;
                foreach (DataGridViewRow fRow in fDataGridView.Rows)
                {
                    DataRowView fDataRowView = (DataRowView)fRow.DataBoundItem;
    
                    if (fDataRowView != null)
                    {
                        DataGridViewComboBoxCell fDataGridViewComboBoxCell = (DataGridViewComboBoxCell)fRow.Cells[2];
                        BindingSource fBindingSource = new BindingSource(this.Department, "Department");
                        fBindingSource.Filter = string.Format("DepartmentKey = {0}", (int)fDataRowView["DepartmentKey"]);
    
                        fDataGridViewComboBoxCell.DataSource = fBindingSource;
                        fDataGridViewComboBoxCell.DisplayMember = "Name";
                        fDataGridViewComboBoxCell.ValueMember = "DepartmentKey";
                    }
                }
            }
        }
    }
    

    知识改变命运,奋斗成就人生!
    2009年6月17日 2:22
    版主
  • 你好,

    问题2和问题1是没有关系的,最好的方式是每个帖子只讨论一个问题,以利于大家的讨论。

    还有就我看来,问题2的要求不是很清楚”有没有类型转换的方法是可以支持很多种方法的.”,能给出一些解释关于你的需求吗?
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年6月18日 5:17
    版主
  • 问题是这样的.
    实体类对象,属性名,属性值,
    public void setPropertyValue(object instanceofEntity, String propertyName, object value)
    {
        Type t = instanceofEntity.GetType();
        PropertyInfo p = t.GetProperty("propertyName");
        p.SetValue(instanceofEntity, Convert.ChangeType(value, p.PropertyType), null);
    }

    但当属性的类型为SqlGuid时,Convert.ChangeType会报错..必须要加判断,如果为SqlGuid需要用SqlGuid.Parse转换.
    原因应该是SqlGuid未实现IConvertible接口吧.
    有没有一种通用的方法可以转换类型的.
    通用转换未实现IConvertible接口的类型.
    上面代码是我手打的,可能会出现问题..
    有人说,充满技术的生活枯燥无味.. 我笑他们不懂.因为只有技术才能充实生活.. 学习就像生活,都需要善于总结,才能发现问题,取得进步.. 生活中充满了数学算式与结构,只要我们善于观察和思考..
    2009年6月18日 12:13
  • Thank X.X.Y for answering my questions, that's exactly what I want..
    I don't know if I can use other collection classes instead of DataTable.

    有人说,充满技术的生活枯燥无味.. 我笑他们不懂.因为只有技术才能充实生活.. 学习就像生活,都需要善于总结,才能发现问题,取得进步.. 生活中充满了数学算式与结构,只要我们善于观察和思考..
    2009年6月18日 12:43
  • 你好,

    你可以看到SqlGuid是没有实现IConvertible接口,所以你的处理方法是正确的。 

    public struct SqlGuid : INullable, IComparable, IXmlSerializable

    ....



    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年6月19日 9:15
    版主
  • 使用 TypeConverter
    知识改变命运,奋斗成就人生!
    2009年6月19日 9:16
    版主