我在winforms窗体里拖了1个datagridview和2个按钮(更新 删除)
1.修改某1行某些单元格的数据,选中该行后点更新 数据库更新
2,选中某行后 点删除 ,dataGirdView删除掉该行 并且数据库也删除了该条记录
[color=#0000FF]问题一:[/color]
假如我现在并不知道我的dataGridView中绑定的数据源到底是何种类型(DataSet,DataTable object 或者sql表都有可能)  也就是说绑定的代码是由其他人写的 而我只写上面2个功能 请问删除功能如何实现呢?
 [color=#0000FF]问题二:[/color]
我并不用DataSet的方法去更新 而是用传对象的方法  比如dataGirdView的显示如下
       学号    姓名   年龄
       01     张三   16
      02     李死   18
我的更新操作思路就是:做1个Student的实体类 然后把选中行的所有值放入对应的student类的字段中 然后向DAL层传递并更新 但是有个问题:在获得字段的时候我需要把 学号字段设置为原始值 (修改无效) 其他设为修改后值  请问如何获得选中行的字段值  并指定该值是用新的还是原始的???  
能把完整代码写出来的我再+100分  捆饶我N天了 要疯了....

解决方案 »

  1.   

    问题一,可以gettype获取数据源类型,反射
    问题2,如果你的类的方法应该有个返回结果,如果更新到数据库成功那么你的显示就是新值,否则就是旧值
    先说思路,具体代码我看着写写吧
      

  2.   

    问题一的解决方法用this.dataGridView1.DataSource.GetType().Name获取不同的类型,来根据不同的数据源做不同的处理
      switch (this.dataGridView1.DataSource.GetType().Name)
                {
                    case "DataTable":
                        //应对不同的类型做处理
                        break;
                    case "SqlDataAdapter":
                        break;
                }
      

  3.   

    问题2,
    如果不让客户设定学号,那么将那一列设置为readonly=true
    获取选中行的值
    string x ="";
                foreach (DataGridViewRow dr in dataGridView1.SelectedRows)
                {
                    foreach (DataGridViewCell dc in dr.Cells)
                    {
                        x += dc.Value;
                    }
                }
                MessageBox.Show(x);这样就获取到所有选中行里面的所有值了,按照你需要的方式处理他们,我仅提供思路
    如果你需要按指定来获取列那么你可以用dataGridView1.SelectedRows[0].Cells[0].Value的方式来获取指定cell里面的值!
    在你将你的自定义类作为参数传递到更新的方法的时候,让那个方法返回一个执行结果,如果成功就将修改应用失败就将修改行的内容回滚!
      

  4.   

    看在200分的份上俺就多写点,写详细点嘿嘿 private void button4_Click(object sender, EventArgs e)
            {
                //你的dal既然是负责数据处理的那么你的删除操作应该交给他来处理
                //我想你的ReaderId应该是主键,因为读者编号应该是不能重复的,如果ReaderId不是主键,你之需要将你的主键传递到dal的删除行的方法中去
                //所以你与dal层的接口来说你仅需要传递客户选中需要删除的读者编号到dal层,就行了
                //下面我假定你的dal类有个静态的方法叫DeleteRows作用是删除一条记录,以读者编号作为参数,返回一个bool值标识是否删除成功
                //而你的读者编号则在你的datagridview中显示在第一列
                foreach (DataGridViewRow dr in dataGridView1.SelectedRows)
                {
                    if (DAL.DeleteRows(dr.Cells[0].Value))
                    {
                        //由于datagridview与你的数据源是绑定的所以当你删除了datagridview中的行的时候你的dt也做了相应更改
                        dataGridView1.Rows.Remove(dr);
                        
                    }
                }
               
            
            }        private void button5_Click(object sender, EventArgs e)
            {
                //修改功能就和上面是差不多的
                //我看到你有个类是Reader对吧,包含了详细的一个读者的数据
                //那么在你的dal层我假定有个方法,按照你的想法是希望直接将一个Reader的实例作为参数传递到方法中删除
                //那么我们就这样来做
                
                foreach (DataGridViewRow dr in dataGridView1.SelectedRows)
                {
                    Reader reader = new Reader();
                    reader.ReaderId = dr.Cells[0].Value;
                    DataTable dt = (DataTable)dataGridView1.DataSource;
                    DataRow dr = dt.Select("读者编号 = " + dr.Cells[0].Value)[0];
                    reader.ReaderId = dr[0].ToString();
                    reader.ReaderName=dr[1].ToString();
                    reader.Sex=dr[2].ToString();
                    reader.Address=dr[3].ToString();
                    reader.Phone=dr[4].ToString();
                    reader.ReaderType.ReaderTypeName=dr[5].ToString();
                    reader.Haveborrowcount = dr[6].ToString();
                    if (!DAL.UpData(reader))
                    {
                        //这里就稍微复杂了,由于你的修改动作已经更改了你的数据源的数据,所以
                        //你目前的数据源状态是已经被更改了,如果你的DAL.UpData(reader)执行不成功
                        //那么你需要将你的数据回滚
                        //首先,你需要在datagridview的单元格的编辑事件中将即将被编辑的数据保存到一个临时的对象中
                        //比如每次改动一行就会实例化一个reader然后将修改前的状态保留下来将这些reader放入你的一个list泛型中
                        //当修改失败的时候将的所有list中的reader数据对数据源进行修改回滚到被修改的状态以前,当修改成功以后清空你的list
                    }
                }
            }
      

  5.   

    两个问题其实是一个问题,在datagridview的点击事件里面根据datagridview当前的行构造一个对象后进行操作,注意一定要从datagridview里面取值构造,否则排序或过滤后从dataset或其它数据源得到的数据不正确。
      

  6.   

    问题一的解决方法用this.dataGridView1.DataSource.GetType().Name获取不同的类型,来根据不同的数据源做不同的处理C# code    switch (this.dataGridView1.DataSource.GetType().Name) { case "DataTable": //应对不同的类型做处理 break; case "SqlDataAdapter": break; }
    问题2,
    如果不让客户设定学号,那么将那一列设置为readonly=true
    获取选中行的值C# code    string x =""; foreach (DataGridViewRow dr in dataGridView1.SelectedRows) { foreach (DataGridViewCell dc in dr.Cells) { x += dc.Value; } } MessageBox.Show(x);
    这样就获取到所有选中行里面的所有值了,按照你需要的方式处理他们,我仅提供思路
    如果你需要按指定来获取列那么你可以用dataGridView1.SelectedRows[0].Cells[0].Value的方式来获取指定cell里面的值!
    在你将你的自定义类作为参数传递到更新的方法的时候,让那个方法返回一个执行结果,如果成功就将修改应用失败就将修改行的内容回滚!C# code    private void button4_Click(object sender, EventArgs e) { //你的dal既然是负责数据处理的那么你的删除操作应该交给他来处理 //我想你的ReaderId应该是主键,因为读者编号应该是不能重复的,如果ReaderId不是主键,你之需要将你的主键传递到dal的删除行的方法中去 //所以你与dal层的接口来说你仅需要传递客户选中需要删除的读者编号到dal层,就行了 //下面我假定你的dal类有个静态的方法叫DeleteRows作用是删除一条记录,以读者编号作为参数,返回一个bool值标识是否删除成功 //而你的读者编号则在你的datagridview中显示在第一列 foreach (DataGridViewRow dr in dataGridView1.SelectedRows) { if (DAL.DeleteRows(dr.Cells[0].Value)) { //由于datagridview与你的数据源是绑定的所以当你删除了datagridview中的行的时候你的dt也做了相应更改 dataGridView1.Rows.Remove(dr); } } } private void button5_Click(object sender, EventArgs e) { //修改功能就和上面是差不多的 //我看到你有个类是Reader对吧,包含了详细的一个读者的数据 //那么在你的dal层我假定有个方法,按照你的想法是希望直接将一个Reader的实例作为参数传递到方法中删除 //那么我们就这样来做 foreach (DataGridViewRow dr in dataGridView1.SelectedRows) { Reader reader = new Reader(); reader.ReaderId = dr.Cells[0].Value; DataTable dt = (DataTable)dataGridView1.DataSource; DataRow dr = dt.Select("读者编号 = " + dr.Cells[0].Value)[0]; reader.ReaderId = dr[0].ToString(); reader.ReaderName=dr[1].ToString(); reader.Sex=dr[2].ToString(); reader.Address=dr[3].ToString(); reader.Phone=dr[4].ToString(); reader.ReaderType.ReaderTypeName=dr[5].ToString(); reader.Haveborrowcount = dr[6].ToString(); if (!DAL.UpData(reader)) { //这里就稍微复杂了,由于你的修改动作已经更改了你的数据源的数据,所以 //你目前的数据源状态是已经被更改了,如果你的DAL.UpData(reader)执行不成功 //那么你需要将你的数据回滚 //首先,你需要在datagridview的单元格的编辑事件中将即将被编辑的数据保存到一个临时的对象中 //比如每次改动一行就会实例化一个reader然后将修改前的状态保留下来将这些reader放入你的一个list泛型中 //当修改失败的时候将的所有list中的reader数据对数据源进行修改回滚到被修改的状态以前,当修改成功以后清空你的list } } }
    两个问题其实是一个问题,在datagridview的点击事件里面根据datagridview当前的行构造一个对象后进行操作,注意一定要从datagridview里面取值构造,否则排序或过滤后从dataset或其它数据源得到的数据不正确。
      

  7.   

    这个问题你需要datagridview的允许删除行那一项选中,再定义datagridview的删除某行时触发的那个方法,忘了那个方法就什么了,自己在MSDN里面查一下,然后再在这个方法里面将选中的行人数据库中删除就要以了,不然的话只能从datagridview中删除,无法从数据库中删除.
      

  8.   

    我已经完成了 修改和删除功能了 但是还有个小问题怎么设置某列为只读列呢???? 比如我想把读者编号列设置为只读的 第3个参数该怎么写呢?
       dt.Columns.Add("读者编号",typeof(string),???); 
    请老大门教我下
      

  9.   

    只读列应该在datagridview里设置对应列的ReadOnly属性为True
      

  10.   

    哇,那么复杂
    只读列设置grid的列的ReadOnly属性为true就行了
      

  11.   


    msdn关于dt.columns.add()方法有3个参数的重载版本的说明如下,可以看出在这里是不能指定只读的
    DataColumnCollection.Add (String, Type, String)  创建一个具有指定名称、类型和表达式的 DataColumn 对象,并将其添加到 DataColumnCollection 中。 你需要在datagridview中控制; 在你将你的datatable绑定到datagridview以后,将你需要设置只读的列按如下格式进行设置即可
    //按列序设置用如下代码
          this.dataGridView1.Columns[0].ReadOnly = true;
    //按列名设置:
         this.dataGridView1.Columns["ResName"].ReadOnly = true;
    随便你选哪一个都可以
      

  12.   

    datagridview.Columns[0].ReadOnly=true;
      

  13.   

    ...
     应该是在按钮中的command 事件中 ,初始化的时候可以在删除按钮中给定commandArguement 的值,(这个值最好是数据行的标识列,删除的时候可以根据标识列删除)
    在按钮的command事件中可以用
    e.commandArguement 获得标识列,然后写sql语句删除, 再重新绑定数据还请高手多多指点 ^_^