WinForm DataGridView学习小记(1)

工作中需要用到DataGridView控件,就花了点时间学习了一下,记录下来方便将来查阅。

DataGridView是在原来的DataGrid控件的基础上增加了更多的特性,更方便用户的拓展和定制使用。在学习这个控件的过程中,我自己比较关注的是以下的一些功能:

1.“非绑定的方式填充数据”:这种方式一般用于数据比较少且数据仅用于显示,在数据量比较大或者需要保存用户的修改和输入的情景,这种方式就不是很实用,但作为一种基本的填充数据的方式,还是需要来了解一下,示例的代码如下:

class TestClass
    {
        public enum Gender
        {
            Male=0,
            Female
        }

        private Gender m_gender = Gender.Male;
        public Gender GetGender
        {
            get { return m_gender; }
            set { m_gender = value; }
        }

        private int m_nValue = -1;
        public int Value
        {
            get { return m_nValue; }
        }

        private String m_nName = "Default";
        public String Name
        {
            get { return m_nName; }
        }

        private int m_nIndex = 1;
        public int Index
        {
            get { return m_nIndex; }
            set { m_nIndex = value; }
        }

        private AnotherClass m_nClass = new AnotherClass();
        public AnotherClass ClassValue
        {
            get { return m_nClass; }
        }
    }

    class AnotherClass
    {
        public AnotherClass()
        {      
            Random random = new Random();
            int nRandom = random.Next(1000);

            for (int i = 0; i < nRandom; i++)
            {                
                m_nValueList.Add(i);
            }
        }

        private List<int> m_nValueList = new List<int>();

        public int TotalValue
        {
            get
            {
                int nTotal=0;
                for (int i = 0; i < m_nValueList.Count; i++)
                    nTotal += m_nValueList[i];

                return nTotal;
            }
        }
    }

List<TestClass> m_testClass = new List<TestClass>();

        public Form1()
        {
            InitializeComponent();

            //this.dataGridView1.Dock = DockStyle.Fill;
            this.Controls.Add(this.dataGridView1);
            //this.Load += new EventHandler(Form1_Load);
            this.Text = "DataGridView calendar column demo";

            int nSize=100;
            for (int i = 0; i < nSize; i++)
            {
                TestClass tmpClass = new TestClass();
                tmpClass.Index = i;

                m_testClass.Add(tmpClass);
            }
        }

private void bindData()
        {
            int nCount = m_testClass.Count;
            //dataGridView1.RowCount = nCount;
            dataGridView1.ColumnCount = 5;

            dataGridView1.Columns[0].Name = "Gender";
            dataGridView1.Columns[1].Name = "Name";
            dataGridView1.Columns[2].Name = "Value";
            dataGridView1.Columns[3].Name = "Index";
            dataGridView1.Columns[4].Name = "ClassValue";

            for (int i = 0; i < nCount; i++)
            {
                DataGridViewRow row = new DataGridViewRow();

                //Gender cell
                DataGridViewComboBoxCell genderCell = new DataGridViewComboBoxCell();
                Array genders = Enum.GetValues(typeof(TestClass.Gender));
                foreach(object obj in genders)
                    genderCell.Items.Add(obj);
                genderCell.Value = m_testClass[i].GetGender;
                row.Cells.Add(genderCell);

                //name cell
                DataGridViewCell nameCell = new DataGridViewTextBoxCell();
                nameCell.Value = m_testClass[i].Name;
                row.Cells.Add(nameCell);

                //value cell
                DataGridViewCell valueCell = new DataGridViewTextBoxCell();
                valueCell.Value = m_testClass[i].Value.ToString();
                row.Cells.Add(valueCell);

                //index cell
                DataGridViewCell indexCell = new DataGridViewTextBoxCell();
                indexCell.Value = m_testClass[i].Index.ToString();
                row.Cells.Add(indexCell);

                //classvalue cell
                DataGridViewCell classValueCell = new DataGridViewTextBoxCell();
                classValueCell.Value = m_testClass[i].ClassValue;
                row.Cells.Add(classValueCell);

                dataGridView1.Rows.Add(row);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            bindData();
        }
在这个例子中,我定义了TestClass类,并在这个类中声明了几个属性,这些属性包括枚举类型、类类型、内置类型等,之所以这么设置,也是为了能够更全面地学习这个功能,在窗口加载的函数中,我为每个一个实例对象声明了一个行对象,并利用实例对象的值来填充该实例对象,然后把它显示在DataGridView控件上,值得一提的是,在这里我选用了DataGridViewComboBoxCell类型的单元格来显示枚举类型,查阅MSDN可以发现,框架中已经为我们实现了很多种单元类型,通常情况下我们可以很方便地利用这些类型来填充我们的数据,当然如果我们想用自己定义的控件,就得通过定制的方式来实现,这是后话,我们一会儿再说。另外,这种“非绑定的数据填充方式”在数据对DataGridView上的单元值进行了修改之后,控件并不会自动地把这些值反馈给内部对象(在这里就是m_testClass),这或许也是为什么MSDN建议我们仅在不需要修改内部数据的情况下才使用这种方式来填充数据的原因吧。


2. 绑定数据源的方式来填充数据:这种方式相比于第一种方式,最大的好处就是简化了数据填充和更新的操作,我们只需要利用DataGridView的DataSource属性就可以很方便地把一个数据源和一个DataGridView对象绑定在一起,并在发生修改时自动实现更新,二话不说,先上示例代码:

private void Form1_Load(object sender, EventArgs e)
        {
            //bindData();

            this.dataGridView1.DataSource = bindingSource1;
            bindingSource1.DataSource = m_testClass;
        }
其它的地方和第一例相同。可以看到,在这里我们首先通过DataSource 属性将一个bindingSource1对象和控件联系起来,然后再把bindingSource1的数据源设置m_testClass,就这么简单地两句话,系统就会自动地把m_testClass中的公有属性填充到表格中,完成操作,当然MSDN中提醒我们,用于充当数据源的对象只有是一些实现了特殊接口的类的实例才行(IList, IBindingList, etc.) 当然这样自动填充的功能方便是方便,但有时候并非完全是我们需要的样子,比如说,m_testClass中的ClassValue属性是自定义的一个类,在自动填充的时候,就会把这个类的信息填充到表格中,在这里,我们假设我们并不希望填充这个信息,而是希望填充AnotherClass类的TotalValue这个属性,因此我们在单元格的格式化函数中对自动填充的过程进行修改,如下所示:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            if (dataGridView1.Columns[e.ColumnIndex].HeaderText == "ClassValue")
            {
                if (e.Value != null)
                    e.Value = (e.Value as AnotherClass).TotalValue;
            }
        }
通过这样的设置,我们就可以修改任意一列显示的数据类型及内容。当然,更进一步地,可能我们还注意到m_testClass中的GetGender属性是个枚举类型,如果可以,我们当然希望利用ComboBox这个控件来显示这个属性值,于是我们进一步修改代码成下面这个样子:

private void Form1_Load(object sender, EventArgs e)
        {
            //bindData();

            this.dataGridView1.DataSource = bindingSource1;
            bindingSource1.DataSource = m_testClass;

            //首先我们先移除系统自动生成的列
            dataGridView1.AutoGenerateColumns = true;
            dataGridView1.Columns.Remove("GetGender");
            //dataGridView1.Columns["GetGender"].Visible = false;

            //定义我们希望的控件类型
            DataGridViewComboBoxColumn column = new DataGridViewComboBoxColumn();
            column.DataSource = Enum.GetValues(typeof(TestClass.Gender)); //这里设置该控件的数据源,枚举类型的所有值
            column.DataPropertyName = "GetGender";//这里设置该控件的值所关联的对象,表示我们希望这个控件的值和“GetGender”这个属性关联
            column.Name = "Gender";
            dataGridView1.Columns.Add(column);

            //connect combo box to mygender
            this.comboBox1.DataSource = Enum.GetValues(typeof(TestClass.Gender));
            this.comboBox1.SelectedIndex = 0;
        }
在这里我们首先移除系统为我们自动填充的列对象,然后手动创建了ComboBox的列实例,并通过设置其数据源和关系的对象完成控件的定制操作。这里值得注意的是DataPropertyName 属性的设置,通常我们通过DataSource来设置整个控件全部的数据源,它可以是表,可以是list等等,但有时候我们希望控件中的某一列和表中的某一个列进行关联,这时候就可以通过DataPropertyName进行设置,如果说DataSource是全局性的数据源定义,DataPropertyName就可以认为是更精细的控制。


在这里我们只是简单地介绍了如何手动和自动地实现DataGridView控件中数据的填充,用的也都是内置的控件类型,有时候我们拓展了某种控件类型,并希望在表格中能够使用它,这时候就需要更复杂的方式来实现,这部分内容会在下篇文章中有详细的记录。


参考自:http://msdn.microsoft.com/zh-cn/library/k39d6s23%28v=vs.110%29.aspx

DataGridView控件用法合集 1. DataGridView当前的单元格属性取得、变更 2. DataGridView编辑属性 3. DataGridView最下面一列新追加行非表示 4. DataGridView判断当前选中行是否为新追加的行 5. DataGridView删除行可否设定 6. DataGridView行列不表示和删除 7. DataGridView行列宽度高度设置为不能编辑 8. DataGridView行高列幅自动调整 9. DataGridView指定行列冻结 10. DataGridView列顺序变更可否设定 11. DataGridView行复数选择 12. DataGridView选择的行、列、单元格取得 13. DataGridView指定单元格是否表示 14. DataGridView表头部单元格取得 15. DataGridView表头部单元格文字列设定 16. DataGridView选择的部分拷贝至剪贴板 17. DataGridView粘贴 18. DataGridView单元格上ToolTip表示设定(鼠标移动到相应单元格上时,弹出说明信息) 19. DataGridView中的ContextMenuStrip属性 20. DataGridView指定滚动框位置 21. DataGridView手动追加列 22. DataGridView全体分界线样式设置 23. DataGridView根据单元格属性更改显示内容 24. DataGridView新追加行的行高样式设置る 25. DataGridView新追加行单元格默认值设置 26. DataGridView单元格数据错误标签表示 27. DataGridView单元格内输入值正确性判断 28. DataGridView单元格输入错误值事件的捕获 29. DataGridView行排序(点击列表头自动排序的设置) 30. DataGridView自动行排序(新追加值也会自动排序) 31. DataGridView自动行排序禁止情况下的排序 32. DataGridView指定列指定排序 33. DataGridView单元格样式设置 34. DataGridView文字表示位置的设定 35. DataGridView单元格内文字列换行 36. DataGridView单元格DBNull值表示的设定 37. DataGridView单元格样式格式化 38. DataGridView指定单元格颜色设定 39. DataGridView单元格文字字体设置 40. DataGridView根据单元格值设定单元格样式 41. DataGridView设置单元格背景颜色 42. DataGridView行样式描画 43. DataGridView显示行号 44. DataGridView焦点所在单元格焦点框不显示的设定 45. DataGridView列中显示选择框CheckBox 46. DataGridView中显示下拉框ComboBox 47. DataGridView单击打开下拉框 48. DataGridView中显示按钮 49. DataGridView中显示链接 50. DataGridView中显示图像 51. DataGridView编辑中单元格控件取得 52. DataGridView输入自动完成 53. DataGridView单元格编辑时键盘KEY事件取得 54. DataGridView下拉框(ComboBox)单元格编辑时事件取得 55. DataGridView下拉框(ComboBox)单元格允许文字输入设定 56. DataGridView根据值不同在另一列中显示相应图片 57. DataGridView中显示进度条(ProgressBar) 58. DataGridView中添加MaskedTextBox 59. DataGridView中Enter键按下焦点移至旁边的单元格 60. DataGridView行集合化(Group)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值