CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  .NET技术 >  C#

高分请指教:如何用dataGrid实现编辑datatable中的单行记录(行式编辑窗口)?

楼主clearma(明天早起床)2004-09-03 18:25:12 在 .NET技术 / C# 提问

即表的某列变行样式,一行记录变为一列。  
  在winform下,  
  由于表的列不固定,所以不易实现在Form中固定label(显示提示)、textbox(或comboBox等)录入某行的记录内容。所以想采用dataGrid来实现,第一列表示提示,第二列表示录入的内容。  
  现在的问题是,第二列的录入样式不确定,可能是textBox,可能是combobox,可能是日期控件,可能是checkbox,如果自定义DataGridTextBoxColumn,加入combobox,日期控件,checkbox等,在录入时某行的改变会影响到相同类型的行的内容。  
   
  金蝶软件实现了类似的功能。有遇到过这种情况的请多多指教。由代码最好。  
  或者请提出设计思路。  
  问题点数:100、回复次数:13Top

1 楼yblcgw(黑马之王)回复于 2004-09-03 18:57:19 得分 40

思路:获取当前鼠标的x,y,然后根据x,y获取当前的行和列(以上完全可以实现,没有问题)然后用switch来显示不同的控建,我的就是这么做的,不知道哪位高手还有其它的想法Top

2 楼clearma(明天早起床)回复于 2004-09-03 19:17:44 得分 0

我有一个表1,存放要编辑的另外一个表2的结构,所以行列的获取好办。  
  如表1  
  id,name,colType   colName  
  1       姓名     text       name  
  2       性别     combobox     sex  
  3       出生年月   DataTimePicker   birthday  
  4       婚否     checkbox   isSex  
   
  表2  
  id,name,sex,birthday,isSex  
  1   张三     0       2004-01-01   0  
  2   里斯     1       2004-01-01   0  
   
  在表1中赠加一列(value)作为存放输入内容的值,然后dataGrid绑定到表1,  
   
  dataGrid两列,第一列mappingname:   name(表1)  
  第二列     mappingname   :value(表1)  
   
  根据操作时时新增还是修改,决定是否提前把表2中的某行的数据加载到表1的value中  
   
  这样dataGrid实际就是4行,如下:  
  name                   value  
  姓名                   _________(textbox)  
  性别                   ________(combobox)    
  出生年月           ________(DataTimePicker)  
  婚否                   ________(checkBox)  
  出生地               ________(combobox)  
   
   
   
  问题在于比如设置dagaGrid第二行combobox类型时,他的数据源与其他行(还有很多行)的combobox的数据源不易区分。  
  当重写DataGridTextBoxColumn的getrowValue时,容易出现第二行与其他行的数据一致的情况。  
   
  当重写Edit时,倒没有问题,也就是说当鼠标点击某个cell时,出来的控件都是对的,因为这时可以获取rowNum,我可以使用DataRow来找到表1种的这一行,根据colType然后决定显示哪一个控件。  
   
  这种方法是否可行。  
  Top

3 楼zhpsam109(JACKY.昊昊)回复于 2004-09-03 19:34:35 得分 20

录入时某行的改变会影响到相同类型的行的内容???怎么会影响呢?Top

4 楼clearma(明天早起床)回复于 2004-09-03 19:48:58 得分 0

回复人:   zhpsam109(孤寂无边)   (   )   信誉:100     2004-09-03   19:34:00     得分:   0      
    录入时某行的改变会影响到相同类型的行的内容???怎么会影响呢?  
  -----------------------  
  因为DataGridTextBoxColumn中只有1个TextBox,难道编辑完一个cell后,必须要重新GetColumnValueAtRow码?有可能啊。否则的话,当点击下一个cell时,值会跟前一个cell的值相同。  
  我在看看。  
     
     
  Top

5 楼clearma(明天早起床)回复于 2004-09-03 21:35:38 得分 0

如上,如果点击第二行的第二列的cell则首先会触发edit事件,好像接着还会触发getColumnValueAtRow,重新遍历每一行,我在GetColumnValueAtRow中设置了当前combobox的dataSource,所以最后第二行的第二列的cell的datasource是最后一个combobox类型的cell的数据源,而非当前cell所对应的数据源。  
  这个问题怎么办?Top

6 楼clearma(明天早起床)回复于 2004-09-04 09:33:55 得分 0

还是没解决阿。  
  请明白datagridtextboxcolumn   类的高手指点一下事件的触发过程。Top

7 楼lovemeet(天意)回复于 2004-09-04 12:01:53 得分 20

yblcgw(黑马之王)提到的我看差不多。  
  private   void   dataGrid_MouseDown(object   sender,   System.Windows.Forms.MouseEventArgs   e)  
  {  
                    int   i=   this.dataGrid   .HitTest((new   Point(e.X,   e.Y))).Row   ;  
    int   j=this.dataGrid   .HitTest   ((new   Point   (e.X   ,e.Y   ))).Column   ;  
  if(!(j==-1||   i==-1   ))  
  {       this.btnDelete   .Enabled   =true;           dgCellContext=Convert.ToInt16   (this.dataGrid   [i,0]);  
  UserNameDelete=Convert.ToString   (this.dataGrid   [i,1]);                 }  
  else    
  {  
  this.btnDelete   .Enabled   =false;  
  }  
          }  
  获得DataGrid的行号和列号不难Top

8 楼clearma(明天早起床)回复于 2004-09-06 17:51:07 得分 0

我的意思是把dataGridColumnStyle定义为包含多个控件的组件,控件的显示与否与实际数据源的每行(或者说dataGrid的每行)有关。  
          但是由于我不明白样式对象dataGridColumnStyle的事件触发过程,比如在用鼠标点击一个单元格后会触发那些事件,造成了在实际dataGrid邦定样式,邦定数据源后,这一列中相同类型的cell,会出现相同值的情况。(估计每点击cell后重新执行了GetColumnValueAtRow)。我的程序中也是用如下方式实现的:  
   
   
  protected   override   object   GetColumnValueAtRow(System.Windows.Forms.CurrencyManager   source,   int   rowNum)  
  {  
          object   ReturnValue=null;  
          DataRow   Dr=DataSet.Tables   [1].Rows   [rowNum];  
          string   FilterString;  
          switch   ((string)Dr["colType"])  
          {  
  case   "text":  
  ReturnValue=base.GetColumnValueAtRow(source,   rowNum);  
  break;  
  case   "list":  
  //获取数据源的值  
  if   (CurrentNum!=0)         //CurrentRow鼠标点击行  
  {  
          if(   CurrentNum!=rowNum)  
                            {  
                rowNum=CurrentNum;  
                Dr=DataSet.Tables   [1].Rows   [rowNum];  
          }  
  }  
                    /*下面是我的combobox数据源的加载过程,因为多个combobox的数据源是一个表,但是他们的类别代码不同,就好比性别,身份,学历等下拉列表内容都放在一个表中,通过某编号来区分。所以combobox中要求出现内容不一样,我想这针对多个表也是如此吧。  
  */  
   
  FilterString   ="deptItemId='"+(string)Dr["id"]+"'";  
   
  DataView   dv=new   DataView   (DataSet.Tables   "dept_item_code"],FilterString,"id",DataViewRowState.CurrentRows);  
  ColumnComboBox.DataSource   =dv;  
  ColumnComboBox.DisplayMember   ="name";  
  ColumnComboBox.ValueMember   =   "id";  
  //DataView   dv   =   (DataView)this.ColumnComboBox.DataSource;  
                    //如果这种方式引用,毫无疑问comBoBox中显示的是上一个combobox应该显示的内容。  
   
  object   s   =     base.GetColumnValueAtRow(source,   rowNum);  
   
  int   rowCount   =   dv.Count;  
  int   i   =   0;  
  while   (i   <   rowCount)  
  {  
                          if(   s.Equals(dv[i][this.ColumnComboBox.ValueMember]))  
        {  
            break;  
        }  
  ++i;  
  }  
  FilterString="";  
  if(i   <   rowCount)  
            ReturnValue=dv[i][this.ColumnComboBox.DisplayMember];  
                    break;  
            case   "list2":  
          ReturnValue=base.GetColumnValueAtRow(source,   rowNum);  
  break;  
            case   "date":  
  ReturnValue=base.GetColumnValueAtRow(source,   rowNum);  
  break;  
            case   "checkbox":  
  ReturnValue=base.GetColumnValueAtRow(source,   rowNum);  
  break;  
          default:  
  ReturnValue=base.GetColumnValueAtRow(source,   rowNum);  
  break;  
          }  
          return   ReturnValue;  
  }  
   
  代码写的很糟糕,不好意思,为了调试有些东西是临时加上的,还没有优化。  
  其实目前只判断了list型的,即combobox型的,其他的控件的返回值都是类似于textbox的。  
  Top

9 楼clearma(明天早起床)回复于 2004-09-09 11:35:14 得分 0

upTop

10 楼happy3613(happy3613)回复于 2004-09-09 13:43:01 得分 20

void   DataGrid1_UpdateCommand(object   source,   System.Web.UI.WebControls.DataGridCommandEventArgs   e)  
          {  
                  SqlConnection   myConnection   =   new   SqlConnection(ConfigurationSettings.ConnectionStrings["SqlServices"].ConnectionString);  
   
                  string   id1   =   DataGrid1.Items[(int)e.Item.ItemIndex].Cells[0].Text;  
                  string   sl=((TextBox)e.Item.Cells[4].Controls[0]).Text;  
                  DataTable   dt   =   (DataTable)Session["myTable"];  
                  dt.Rows[e.Item.ItemIndex][3]   =   sl.ToString();  
                  dt.Rows[e.Item.ItemIndex][6]   =   Convert.ToDouble(dt.Rows[e.Item.ItemIndex][3])   *   Convert.ToDouble(dt.Rows[e.Item.ItemIndex][4]);  
                  dt.AcceptChanges();  
                  DataGrid1.EditItemIndex   =   -1;  
                  DataGrid1.DataSource   =   ((DataTable)Session["myTable"]).DefaultView;  
                  DataGrid1.DataBind();  
          }Top

11 楼clearma(明天早起床)回复于 2004-09-09 19:35:44 得分 0

楼上请问什么思路,webform   与winform毕竟有不同,你的代码我不太明白。Top

12 楼clearma(明天早起床)回复于 2004-09-10 13:23:24 得分 0

今天重新看了msdn中的GetColumnValueAtRow,感觉以前分析的不对阿。  
   
  protected   internal   virtual   object   GetColumnValueAtRow(  
        CurrencyManager   source,  
        int   rowNum  
  );  
  看他的两个参数,source是当前的绑定管理对象,rowNum则是指定数据源的Position  
  不知道微软的代码怎么写的,估计也就是利用了CurrencyManager的,然后强制转换为dataview等,然后利用dataview[rowNum]获取出数据源的值。  
   
   
  以下内容通过设置断点分析,paint的内容为猜测,请各位指教:  
   
  (1)dataGrid首先画出了框架,标题,边框等。这时肯定要用到tableStyle(不管是否自定义,特别是headerText,width等)  
  (2)接着从邦定数据源的第0行开始初始每个cell的值,使用GetColumnValueAtRow方法。  
  paint的顺序是按照列来进行的。即(0,0),(0,1),(0,n)  
  (3)paint的过程不太清楚,比如画表格线,用的text的边框还是画的线呢?  
  (3)当重复经过某一列时,比如此列的类型为ComboBoxColumn(继承自textBoxColumn),那么还是要使用GetColumnValueAtRow()方法。  
  (4)完成  
  (5)如果鼠标点击某个cell(非其他),则事件的触发不很清楚,  
  是mouseDown,mouseEnter,mouseUp,还是触发离开(Leave)CurrentCellChanged等  
  这应该涉及到多个对象的事件触发过程。  
  (6)接下来应该是Edit()方法,这时会不会GetColumnValueAtRow()  
  (7)如果修改后离开的话应该有Commit(),是否有ConcedeFocus()呢?  
   
  我的问题是,我的ComboBoxColumn   列中只有一个ComboBox对象(无可厚非吧?),但是却要  
  根据数据源的行(rows[x])来动态决定所对应的ComboBox的数据源(好像不合理阿,但是必须要这样,其实是同一表,但是dataview的filter语句不同)  
   
  (a)可以在鼠标点击cell时通过重写edit()方法来设定当前cell的ComboBox的数据源,  
  (b)但是在离开这个cell后,会触发paint(),paint肯定会使用GetColumnValueAtRow()来重绘所有行  
   
  (c)如果在GetColumnValue()中设置ComboBoxColumn   列的ComboBox数据源,(因为这一列中针对某行ComboBox的数据源不同,显示的textBox.text就不同)}  
  (d)当paint完成后,GetColumnValueAtRow()中设定的是最后一行的ComboBox的数据源。这样鼠标点击的那个cell的ComboBox的数据源也被改变了  
   
  情况就是这样,应该怎么办?我相信肯定有办法,但是我现在陷入谜团了。败了。  
  Top

13 楼clearma(明天早起床)回复于 2004-09-13 14:43:58 得分 0

再up!到底Top

相关问题

  • 如何编辑DATAGRID
  • datagrid编辑问题!!
  • datagrid 多行编辑
  • datagrid中的编辑
  • Winform中,用DataGrid编辑数据时,如何自定义异常(DataTable的异常)!
  • 关于单行编辑控件的问题?
  • 寻求单行编辑器(sle)的单、双击事件,急!
  • 鼠标不能选种单行编辑器?
  • datagrid为何不能编辑??
  • DataGrid控件编辑问题

关键词

  • 录入
  • cell
  • 数据
  • 控件
  • datagrid
  • 样式
  • 鼠标
  • 内容
  • dv
  • combobox

得分解答快速导航

  • 帖主:clearma
  • yblcgw
  • zhpsam109
  • lovemeet
  • happy3613

相关链接

  • CSDN .NET频道
  • .NET类图书
  • C#类图书
  • .NET类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo