【原创】PDA DataGrid的滚动条事件处理

之前介绍的使得PDA datagrid 能够进行编辑的实现方法:利用一个隐藏的textbox控件,当用户点击datagrid单元格变化引发事件CurrentCellChanged发生,在该事件中设置textbox可见,且显示信息即为当前选中的单元格的文本,当修改文本信息焦点离开textbox时,将textbox中的内容写入datagrid绑定的datatable中,这样就实现利用一个覆盖在单元格上的可编辑的textbox使得datagrid可编辑的功能。

 

但是它存在一个问题:当移动DataGrid的滚动条时,textbox仍在原来的位置,没有失去焦点。要解决这个问题,就需要能够捕捉到datagrid的拖动滚动条事件。

  • 由于滚动条是当内容显示不够时,自动由datagrid提供的,观察发现在datagrid的相应事件里没有关于滚动条的事件。
  • 考虑到滚动条移动,可能会导致paint事件,但是实践发现,DataGrid的滚动条操作,并没有引发paint事件(可能是因为滚动条滚动过程只是将本来已经画好的窗体挪过来,因为移动设备的屏幕很小,显示有限,它不是一个边画边更新的过程)。同样的道理,实验利用Form的Paint事件同样没有响应。
  • 然后考虑用mousedown事件,捕捉鼠标点击位置坐标,但是发现鼠标移动到滚动条后就不返回点击位置坐标了。
  • 综上考虑,如果想从DataGrid的事件中找到关于滚动条移动的事件不太可能,那我们是否可以获得datagrid中的滚动条对象呢??

查资料后发现,原来Datagrid控件是由三个控件组成,这些控件可以利用DataGrid.controls属性获得,利用DataGrid.controls.count可以获得控件的个数。

那么就可以按照DataGrid.controls[i]用i下标来访问每一个控件。

通过编程测试找到

DataGrid.controls[0]对应的是水平滚动条HScroll

DataGrid.controls[1]对应的是垂直滚动条VScroll

 

HScrollBar hScrollBar = null;
VScrollBar vScrollBar = null;

//绑定DataGrid滚动事件
        private void BindScrollEvent()
        {
            foreach (Control c in this.Controls)
            {
                if (c is HScrollBar) hScrollBar = (HScrollBar)c;
                if (c is VScrollBar) vScrollBar = (VScrollBar)c;
            }
            if (hScrollBar != null)
            {
                hScrollBar.ValueChanged -= new EventHandler(DataGrid_HScrollEvent);
                hScrollBar.ValueChanged += new EventHandler(DataGrid_HScrollEvent);
            }
            if (vScrollBar != null)
            {
                vScrollBar.ValueChanged -= new EventHandler(DataGrid_VScrollEvent);
                vScrollBar.ValueChanged += new EventHandler(DataGrid_VScrollEvent);
            }
        }

 

因此我们可以针对水平滚动条,自己编写事件触发过程:

 

//水平滚动事件
        private void DataGrid_HScrollEvent(object sender, EventArgs e)
        {
            if (txtedit.Focus())
            {
                txtedit.Visible = false;
            }
        }
        //垂直滚动事件
        private void DataGrid_VScrollEvent(object sender, EventArgs e)
        {
            if (txtedit.Focus())
            {
                txtedit.Visible = false;
            }
        }

这样就实现了当点击datagrid的滚动条时让textbox失去焦点。

 

完整代码

 

using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections;
using System.Data;

namespace SmartDeviceProject1
{
    public class datagridEx :DataGrid,ISupportInitialize
    {
        DataGridCell editcell = new DataGridCell();
        Rectangle cellpos = new Rectangle();
        TextBox txtedit = null;
        HScrollBar hScrollBar = null;
        VScrollBar vScrollBar = null;
        bool isUpdateMode = false;
        bool isEditMode = false;

        public datagridEx()
        {
            InitTextBox();
            BindScrollEvent();                        
        }
        /// <summary>
        
/// 初始化可编辑TextBox     
        
/// </summary>
        private void InitTextBox()
        {
            txtedit = new TextBox();
            this.Controls.Add(txtedit);
            txtedit.Visible = false;
            txtedit.BringToFront();
            txtedit.Text = "grn";
            txtedit.KeyPress -= new KeyPressEventHandler(txedit_KeyPress);
            txtedit.KeyPress += new KeyPressEventHandler(txedit_KeyPress);
        }
        //绑定DataGrid滚动事件
        private void BindScrollEvent()
        {
            foreach (Control c in this.Controls)
            {
                if (c is HScrollBar) hScrollBar = (HScrollBar)c;
                if (c is VScrollBar) vScrollBar = (VScrollBar)c;
            }
            if (hScrollBar != null)
            {
                hScrollBar.ValueChanged -= new EventHandler(DataGrid_HScrollEvent);
                hScrollBar.ValueChanged += new EventHandler(DataGrid_HScrollEvent);
            }
            if (vScrollBar != null)
            {
                vScrollBar.ValueChanged -= new EventHandler(DataGrid_VScrollEvent);
                vScrollBar.ValueChanged += new EventHandler(DataGrid_VScrollEvent);
            }
        }

        DataGridCell currentcell;
        protected override void OnCurrentCellChanged(EventArgs e)
        {
            if (isUpdateMode)
            {
                base.OnCurrentCellChanged(e);
                return;
            }
            currentcell = this.CurrentCell;
            if (isEditMode && !this.CurrentCell.Equals(editcell))
            {
                isUpdateMode = true;
                this[editcell.RowNumber, editcell.ColumnNumber] = txtedit.Text;
                this.CurrentCell = currentcell;
                this.Visible = true;
                txtedit.Visible = false;
                isUpdateMode = false;
                isEditMode = false;
            }
            editcell = this.CurrentCell;
            cellpos = this.GetCellBounds(editcell.RowNumber, editcell.ColumnNumber);
            txtedit.Left = cellpos.Left  - 1;
            txtedit.Top = cellpos.Top  - 1;
            txtedit.Width = cellpos.Width + 2;
            txtedit.Height = cellpos.Height + 2;

            txtedit.Visible = true;            
            txtedit.Text = this[editcell.RowNumber, editcell.ColumnNumber].ToString();

            txtedit.BringToFront();
            txtedit.Focus();
            txtedit.SelectAll();
            isEditMode = true;

            base.OnCurrentCellChanged(e);
        }
      
        private void txedit_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                txtedit.Visible = false;
                this[currentcell.RowNumber, currentcell.ColumnNumber] = txtedit.Text;
                this.Focus();
                if (currentcell.RowNumber +1 < this.VisibleRowCount)
                    currentcell.RowNumber = currentcell.RowNumber + 1;
                this.CurrentCell = currentcell;
                                
                isUpdateMode = false;
                isEditMode = true;
            }
        }

        //水平滚动事件
        private void DataGrid_HScrollEvent(object sender, EventArgs e)
        {
            if (txtedit.Focus())
            {
                txtedit.Visible = false;
            }
        }
        //垂直滚动事件
        private void DataGrid_VScrollEvent(object sender, EventArgs e)
        {
            if (txtedit.Focus())
            {
                txtedit.Visible = false;
            }
        }

        #region ISupportInitialize接口实现
        public void BeginInit()
        {            
        }
        public void EndInit()
        {
        }
        #endregion

    }   
}

 

posted on 2012-07-02 13:32  LeeWenjie  阅读(769)  评论(0编辑  收藏  举报

导航