20.3 使用技巧7

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的

20.3.11 实现文本单元格中显示下拉框并设置值

在实际工作中,为了防止用户乱填写数据,开发者往往需要给出固定的几个值,用户只能在那几个值里面选择,在DataGridView中可以通过设置DataGridViewComboBoxCell来实现,但是一列的下拉框单元格,没有文本单元格视觉效果那么好,造成用户体验并不是很好。在本节将实现当点击文本单元格开始编辑时,就出现下拉框,编辑完成后又恢复为文本单元格。

第一种方法,直接在点击DataGridViewTextBoxCell的单元格时,将其替换为DataGridViewComboBoxCell,选定值后再换回来。

【例 20.20【项目:code20-020】文本单元格显示下拉框并设置值。

        private void Form1_Load(object sender, EventArgs e)

        {

            //增加对单元格的值发生改变时的处理

            dgv.CellValueChanged += dgv_CellValueChanged;

        }

        //当单元格被点击时

        private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)

        {

            //获得点击单元格的列索引和行索引

            int cellrowindex, cellcolindex;

            cellcolindex = e.ColumnIndex;

            cellrowindex = e.RowIndex;

            //当点击第2列(索引1)的单元格时显示ComboBox

            if (cellcolindex != 1)

                return;

            //获得当前单元格的值

            string cellvalue = (string)dgv[cellcolindex, cellrowindex].Value;

            DataGridViewComboBoxCell dcb = new DataGridViewComboBoxCell();

            //向DataGridViewComboBoxCell下拉列表中填入数据

            dcb.Items.Add("第1中学");

            dcb.Items.Add("第2中学");

            dcb.Items.Add("第3中学");

            //设置值为原单元格的值

            dcb.Value = cellvalue;

            //将单元格设置为DataGridViewComboBoxCell

            dgv[cellcolindex, cellrowindex] = dcb;

        }

         //当单元格的值发生改变时

        private void dgv_CellValueChanged(object sender, DataGridViewCellEventArgs e)

        {

            //获得单元格的列索引和行索引

            int cellrowindex, cellcolindex;

            cellcolindex = e.ColumnIndex;

            cellrowindex = e.RowIndex;

            //获得当前单元格的值

            string cellvalue = (string)dgv[cellcolindex, cellrowindex].Value;

            DataGridViewTextBoxCell dt = new DataGridViewTextBoxCell();

            dt.Value = cellvalue;

            //将单元格设置为DataGridViewTextBoxCell

            dgv[cellcolindex, cellrowindex] = dt;

        }

运行结果如下图所示:

图20-25 下拉框单元格与文本单元格交换

如图20-25,这一种方法在单元格焦点未失去时,将一直显示为下拉框单元格。因为DataGridViewComboBoxCell没有提供类似ComboBox.SelectedIndexChanged事件,无法捕获到下拉框索引改变这个事件。

第二种方法,首先明确几个概念:

1、DataGridView控件可以包含子控件,通过DataGridView.Controls 属性访问即可,这样就可以将ComboBox控件包含进去,当然其它控件也可以。

2、当ComboBox加入后,需要确定它的大小和位置,需要调用DataGridView的GetCellDisplayRectangle方法,具体语法:

public Rectangle GetCellDisplayRectangle( int columnIndex, int rowIndex, bool cutOverflow )

参数说明:

  1. columnIndex:单元格的列索引。
  2. rowIndex:单元格的行索引。
  3. cutOverflow:如果只返回该单元格的显示部分,则为true;如果返回整个单元格界限,则为false。

返回值:

  1. 表示单元格显示区域的矩形,也就获得了该区域的位置和尺寸。这是一个Rectangle对象。

当获得Rectangle对象后,设置ComboBox的大小和位置与它相同就可以了。

3、当点击指定的单元格(CellClick)时或者单元格获得焦点(CellEnter)时,设置显示ComboBox。

4、当从ComboBox选择了值,将值写回单元格。就可以使ComboBox隐藏起来。

以上操作中可能遇到的几个问题:

1、单元格获得了值,但不会像正常情况下选择了值或者输入了值,DataGridView的最下面就会出来新的一行,而要在其他列输入数据后才会出来新行。这也是很多代码没有解决的问题。这个问题可以使用DataGridView的NotifyCurrentCellDirty方法来通知做了修改。在笔者实际测试时发现有时候一次通知不行,最好是调用此方法两次。

2、当点击某个单元格ComboBox显示出来后,点击其它不应显示ComboBox的单元格时,ComboBox仍然还在原单元格。这个问题只需要点击单元格时先将ComboBox隐藏即可。

3、当点击某个单元格ComboBox显示出来后,也可以输入数据,而不是期望的从ComboBox中的数据。这个问题只需要设置该单元格只读(ReadOnly=true)即可。

【例 20.21【项目:code20-021】文本单元格显示下拉框并设置值。

        //声明一个窗体级的ComboBox变量cb

        ComboBox cb;

        //声明两个Integer保存点击的行列的索引

        int cellrowindex, cellcolindex;

        //当窗体载入后, 将固定的值增加到cb中,

        private void Form1_Load(object sender, EventArgs e)

        {

            //实例化ComboBox,填入数据

            cb = new ComboBox();

            cb.Items.Add("第1中学");

            cb.Items.Add("第2中学");

            cb.Items.Add("第3中学");

            //限制用户输入,使用DropDownList

            cb.DropDownStyle = ComboBoxStyle.DropDownList;

            //不显示

            cb.Visible = false;

            //增加到DataGridView所属控件中

            dgv.Controls.Add(cb);

            //同时增加ComboBox的索引改变事件(SelectedIndexChanged)

            cb.SelectedIndexChanged += cbChanged;

        }

        //添加ComboBox的SelectedIndexChanged事件具体代码

        private void cbChanged(object sender, EventArgs e)

        {

            //将选好值后将值传给对应的单元格

            dgv[cellcolindex, cellrowindex].Value = cb.Text;

            //隐藏ComboBox

            cb.Visible = false;

            //当单元格写入数据后通知DataGridView做了修改

            dgv.NotifyCurrentCellDirty(true);

            //实测需要两次通知, 一次有时候不行

            dgv.NotifyCurrentCellDirty(false);

        }

        private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)

        {

            //获得点击单元格的列索引和行索引

            cellcolindex = e.ColumnIndex;

            cellrowindex = e.RowIndex;

            //先使ComboBox隐藏

            cb.Visible = false;

            //当点击第2列(索引1)的单元格时显示ComboBox

            if (cellcolindex != 1)

                return;

            //设置单元格只读,不允许用户绕过ComboBox手动输入修改

            dgv[cellcolindex, cellrowindex].ReadOnly = true;

            //获得当前单元格的值

            string cellvalue = (string)dgv[cellcolindex, cellrowindex].Value;

            //获得单元格的大小和位置。

            Rectangle rect;

            rect = dgv.GetCellDisplayRectangle(cellcolindex, cellrowindex, true);

            //设置ComboBox的大小位置与单元格相同

            cb.Top = rect.Top;

            cb.Left = rect.Left;

            cb.Width = rect.Width;

            cb.Height = rect.Height;

            //为了限制用户输入,设置ComboBox的文本为第一个值

            cb.Text = cellvalue;

            //显示ComboBox

            cb.Visible = true;

        }

运行结果如下图所示:

图20-26 从ComboBox中选择值填入单元格

学习更多vb.net知识,请参看vb.net 教程 目录

学习更多C#知识,请参看C#教程 目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.Net学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值