zoukankan      html  css  js  c++  java
  • ASP.new GridView获取隐藏列值的几种方法

    解决方法:

    原文来自:http://www.tzwhx.com/NewShow/newBodyShow/控件_32933.html 作者:lerit 

    1.隐藏列前获取数据

    看这样一个例子(以下均以此为例):用户选择一些查询条件后,点击“查询”按钮。后台需要根据每行中第六列的值是否为1,来设置第三个单元格的背景色为红色。

    这种方法中,后台是在按钮的Click事件中,去数据库取记录,然后得到DataTable,最后将它绑定到GridView中。如果我们需要在GridView的RowDataBound事件中取隐藏列的值,则用Visible属性来设置某一列为隐藏,是没问题的。如下代码:

    	protected void Btn_Query_Click(object sender, EventArgs e)
    {
    
    DataTable dt = new DataTable();
    
    dt=ConstructActiveDataTable();//一个取记录的方法
    
    GV.DataSource = dt;
    GV.DataBind();
    
    GV.Columns[5].Visible = false;//设置第6列为隐藏
    
    }
    
    protected void GV_UpdateData_RowDataBound(object sender, GridViewRowEventArgs e)
    {
       if (e.Row.RowType == DataControlRowType.DataRow)
        {
          if (e.Row.Cells[5].Text.ToString() == "1")//当行中的第六个单元格的值为1时(第六列为隐藏哦)
            {
              e.Row.Cells[2].BackColor = System.Drawing.Color.Red;//设置行中第三个单元格背景色为红色
            }
        }
    }
    

    为什么这样就可以了呢?其实是利用了在隐藏列之前就把数值取到了,然后最后再隐藏列。因为在Click事件中,当GV.DataBind()后,不是执行了GV.Columns[5].Visible = false,而是立刻触发了RowDataBound事件,等执行完了此事件,才继续回去执行的隐藏列的代码。因此,这类特定问题中,只要利用事件或函数调用的顺序关系,即可避免无法取值的问题。

    当然,这一解决方案并非通用,它对代码执行顺序有要求。

    2.分别隐藏列中每个单元格

    有些时候,我们不想用上面那种手动方式(DataBind())来绑定GridView了,而是使用一些已有的数据源控件,比如:objectdatasource控件。将GridView的DataSourceID指定为objectdatasource控件的ID,则objectdatasource控件指定其SelectMethod属性为一个返回类型是集合类型的函数(比如返回DataTable),就会在后台自动去调用这个函数并绑定(具体方法就不说了)。

    那么依然是上面那个应用,根据隐藏列值来设置另一个单元格的背景颜色,上面那个顺序就不可能实现了,因为类似于DataBind的绑定是隐式执行的,虽然他可能也是绑定后立刻触发RowDataBound事件,然后回去执行剩余代码,但是我们不能在剩余代码中再如上面的插入设置列隐藏的代码。因此,依靠控制代码顺序来实现不太可能了,这是第一个问题。另外,还有一个问题(问题提出中所指),就是这个控件比较怪,如果你在用objectdatasource绑定后,设置了一次列的Visible,那么objectdatasource就会重新去绑定一次数据,那么如果隐藏10个列,岂不是要去重新从数据库等数据源重复读十遍数据,这个性能上是不可接受的。

    鉴于这两个原因,必须有别的方法来隐藏列。

    既然列是由单元格形成的,那么一一隐藏单元格肯定也能达到隐藏的效果,但是隐藏后能否获取到其值呢,经过验证,确实可以。不过要注意,Footer,Header和DataRow中的单元格都需要隐藏哦,否则表格就错位了。隐藏的代码放哪里都可以,建议放在RowDataBound事件中,这样每生成一行就去隐藏相应列即可。

    	protected void GV_UpdateData_RowDataBound(object sender, GridViewRowEventArgs e)
    {
    if (e.Row.RowType == DataControlRowType.Header || //如果设置gridview不显示Header,就不写这个(否则报错)
    
       e.Row.RowType == DataControlRowType.DataRow || 
    
       e.Row.RowType == DataControlRowType.Footer)    //如果设置gridview不显示Footer,就不写这个(否则报错)
       
       {
       e.Row.Cells[5].Visible=false;//设置每一行中第六个单元格为隐藏,达到隐藏第六列的目的
    
       }
    
       if (e.Row.RowType == DataControlRowType.DataRow)
        {
          if (e.Row.Cells[5].Text.ToString() == "1")//即使隐藏了,依然可以访问到数值哦
            {
              e.Row.Cells[2].BackColor = System.Drawing.Color.Red;//设置行中第三个单元格背景色为红色
            }
        }
    }
    	 

    依然有人认为这代码不够好,有些人不喜欢用事件,另外也担心性能问题,毕竟每一行都要触发这个事件。

    3.利用新的属性DataKeys和DataKeyNames

    事实上,微软所作的考虑更加周全。针对GridView无法提供行主键的问题,它提供了两个全新的属性:DataKeys和DataKeyNames!其SDK中的描述如下:
    DataKeyNames:获取或设置一个数组,该数组包含了显示在 GridView 控件中的项的主键字段的名称。
    DataKeys:获取一个 DataKey 对象集合,这些对象表示 GridView 控件中的每一行的数据键值。

    也就是说,利用DataKeyNames,可以设置一个多个列,用于作为行的主键字段(这里用主键其实不太合适,因为值时允许重复的),之后利用DataKeys旧可以访问这些列的值了。因此,利用这两个新属性,我们就可以继续使用利用列的Visible属性设置来隐藏列的同时,又可以访问隐藏列的值了。方法如下:

    	GV.Columns[5].Visible = false;//设置第6列为隐藏
    //只需要在设置列为隐藏的地方多加一段代码:
    GV.DataKeyNames = new string[] { "stateid_O2" };
    //假设第六列的列名为stateid_O2
    
    protected void GV_UpdateData_RowDataBound(object sender, GridViewRowEventArgs e)
    {
       if (GridView_UpdateData.DataKeys[e.Row.DataItemIndex]["stateid_O2"].ToString() == "1")
    	//利用这个DataKeys属性来访问隐藏列的值
    {
       e.Row.Cells[2].BackColor = System.Drawing.Color.Red;//设置行中第三个单元格背景色为红色
     }
    }

    4.利用客户端代码来隐藏列

    实际上,我们上面都是在服务器端利用各种方法来隐藏列了,那么这种方法就是服务器端不对列的可见性进行设置,那么显然就不存在无法取值的问题了,那么又要让用户不看到某些列,这就需要客户端的代码css来实现隐藏效果了。可以从上面方法推导出,既可以用css直接隐藏列,也能通过隐藏列的单元格来实现。首先需要一个css:

    	<style type="text/css">
       .hidden { display:none;}
    </style>

    如果GridView的列是事先确定,也就是通过设计器来添加的,那么只需要在设计时,将相应列的FootStyle,HeaderStyle,ItemStyle的CssClass属性为“hidden” 即可。如下图所示:

    截图00

    当然,如果列是动态的,或者隐藏哪一列只有在绑定后才能确定,那么就必须在后台设置css。设置有两种方法:

    一种是设置的css:

    	protected void GridView_UpdateData_RowDataBound(object sender, GridViewRowEventArgs e)
       {
        GV.Columns[5].HeaderStyle.CssClass = "hidden";
        GV.Columns[5].ItemStyle.CssClass = "hidden";
        GV.Columns[5].FooterStyle.CssClass = "hidden";                        
       }

    另一种是设置单元格的css:

    	protected void GV_UpdateData_RowDataBound(object sender, GridViewRowEventArgs e)
    {
    if (e.Row.RowType == DataControlRowType.Header || //如果设置gridview不显示Header,就不写这个(否则报错)
    
       e.Row.RowType == DataControlRowType.DataRow || 
    
       e.Row.RowType == DataControlRowType.Footer)    //如果设置gridview不显示Footer,就不写这个(否则报错)
       
       {
       e.Row.Cells[5].CssClass = "hidden";
       }
    }

    总结:

    第一种方法不太通用,要求在隐藏列前就去访问值,这个是一个约束条件。第二种通过服务器端隐藏列中每个单元格来实现效果,效率一般;第三种应该是标准方式,利用新的属性来达到目的,需要熟悉他的用法;最后一种是在客户端进行隐藏,但是数据还是传到客户端了,如果不介意这样一点多出的数据量,这个应该最容易理解和使用。

  • 相关阅读:
    VS2008 环境中完美搭建 Qt 4.7.4 静态编译的调试与发布 Inchroy's Blog 博客频道 CSDN.NET
    编写可丢弃的代码
    c++ using namespace std; 海明威 博客园
    解决MySQL server has gone away
    nginx upstream 调度策略
    (2006, 'MySQL server has gone away') 错误解决 dba007的空间 51CTO技术博客
    Linux IO模型漫谈(2) 轩脉刃 博客园
    redis源码笔记 initServer 刘浩de技术博客 博客园
    MySQLdb批量插入数据
    词库的扩充百度百科的抓取你知道这些热词吗? rabbit9898 ITeye技术网站
  • 原文地址:https://www.cnblogs.com/ChineseMoonGod/p/3732344.html
Copyright © 2011-2022 走看看