zoukankan      html  css  js  c++  java
  • 【转】ASP.net2。0中解决无法获取 GridView 隐藏列值问题

     

    在 GridView/DetailsView 中如果 BoundField 的 Visible=false 时,  回发的时候无法此列的值(GridViewRow.Cells[cellIndex].Text将为空),网上很多朋友提出了各种各样的解决方案,这里整理一下,并提供示例。

    未反射 GridView 类,不曾仔细阅读其源码,不知内部实现对于 BoundField(普通绑定列),当此列 Visible=false 时,是未执行绑定计算,还是未保持 ViewState,也许这是就是传说的GridView性能由于DataGrid的一点吧。事实上,这样反而给粗心的开发者带来了“莫名其妙”的问题。DataGrid 中 BoundColumn 不存在此问题。

    MSDN 对此是这样的说明:

    备注

    使用 Visible 属性显示或隐藏数据绑定控件中的 DataControlField 对象。

    如果 Visible 属性为 false,则不显示数据值并且不做到客户端的往返行程。如果要往返不可见字段的数据,请将字段名添加到数据绑定控件的 DataKeyNames 属性。
    http://msdn2.microsoft.com/zh-cn/library/system.web.ui.webcontrols.datacontrolfield.visible(VS.80).aspx
    说明:BoundField 类继承自 DataControlField 类。

    事实上,实际项目中,我几乎没有使用隐藏列的经验,即使在 1.x 的 DataGrid 中,为了记录某些有用的隐藏信息,我一般使用模板列中嵌套控件,如label 并设置其visible=false 最佳当然是用 input type=hidden runat=server(注:1.x 中没有 asp:hiddenfield 控件)。
    而 2.0 ,最佳的方案,当然是使用 DataKeys 来存储,不像DataGrid.DataKey ,GridView/DetailsView.DataKeys 可以存储多个值。

    以下为示例代码,代码包含各种方案的“自说明”注释,不再做过多的解释。

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data" %>

    <%--http://community.csdn.net/Expert/TopicView3.asp?id=5646507--%>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <script runat="server">

        
    protected void Page_Load(object sender, EventArgs e)
        
    {
            
    if (!IsPostBack) {
                LoadProductData();
            }

        }
      

        
    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        
    {
            
    // 客户端 CSS 控制隐藏,不安全,毕竟数据还是呈现到客户端了
            e.Row.Cells[3].Style.Add(HtmlTextWriterStyle.Display, "none");
            
    // 设置单元格隐藏, TableCell.Visible=false, OK
            e.Row.Cells[4].Visible = false;
        }

        
        
    protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
        
    {        
            
    int rowIndex = -1;        
            
    switch (e.CommandName) {
                
    case "Select":
                    rowIndex 
    = Convert.ToInt32(e.CommandArgument);
                    GridViewRow row 
    = GridView1.Rows[rowIndex];
                    Response.Write(String.Format(
    "<pre style='color:red'>您选择了第 {0} 行\n当前行 ProductId={1}, CategoryId={2}(两者均由DataKeys获取)\n"
                        (row.RowIndex 
    + 1),
                        GridView1.DataKeys[rowIndex].Values[
    "ProductId"],
                        GridView1.DataKeys[rowIndex].Values[
    "CategoryId"]));                
                    
    for (int columnIndex=0; columnIndex< GridView1.Columns.Count; columnIndex++{
                        DataControlField field 
    = GridView1.Columns[columnIndex];
                        
    string text = null;
                        
    if (field is BoundField) {
                            text 
    = row.Cells[columnIndex].Text;
                        }

                        
    else if (field is TemplateField) {
                            Label lbl 
    = row.Cells[columnIndex].FindControl("lblProductID"as Label;
                            
    if (lbl != null{
                                text 
    = lbl.Text;
                            }

                            
    else {
                                text 
    = row.Cells[columnIndex].Text;
                            }

                        }

                        Response.Write(String.Format(
    "{0}#Type={1}#Visible={2}#CanGetText={3}#Text={4}\n"
                            field.HeaderText, field.GetType().Name.ToString(), field.Visible, 
    !String.IsNullOrEmpty(text), text));
                    }

                    Response.Write(
    "</pre>");
                    
    break;
            }

        }

        
        
    void LoadProductData()
        
    {
            DataTable dt 
    = CreateProductTable();

            GridView1.DataSource 
    = dt;
            GridView1.DataBind();
        }


        
    sample data  
        
        
    protected void Button1_Click(object sender, EventArgs e)
        
    {
            LoadProductData();
        }

    </script>

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        
    <title>Demo6_AccessHiddenGridViewColumnValue</title>
    </head>
    <body>
        
    <form id="form1" runat="server">
        
    <div>
            
    <asp:GridView ID="GridView1" DataKeyNames="ProductId,CategoryId" runat="server" AutoGenerateColumns="False" OnRowCommand="GridView1_RowCommand" OnRowDataBound="GridView1_RowDataBound"  CellPadding="4" ForeColor="#333333">
                
    <Columns>
                    
    <asp:BoundField DataField="ProductID" HeaderText="列0 正常状态"/>
                    
    <asp:BoundField DataField="ProductID" HeaderText="列1 直接设置Visible=false 无法获取值" Visible="False" />
                    
    <asp:BoundField DataField="ProductID" HeaderText="列2 width=0 客户端依然呈现无效">
                        
    <ItemStyle Width="0px" />
                    
    </asp:BoundField>        
                    
    <asp:BoundField DataField="ProductID" HeaderText="列3 客户端 CSS 控制隐藏,不安全,毕竟数据还是呈现到客户端了"/>
                    
    <asp:BoundField DataField="ProductID" HeaderText="列4 设置单元格隐藏, TableCell.Visible=false, OK"/>                
                    
    <asp:TemplateField HeaderText="列5 模板列直接调用 Eval " Visible="False">
                        
    <ItemTemplate>
                            
    <%# Eval("ProductID"%>
                        
    </ItemTemplate>
                    
    </asp:TemplateField>                
                    
    <asp:TemplateField HeaderText="列6 模板列嵌入 Label" Visible="False">
                        
    <ItemTemplate>
                            
    <asp:label ID="lblProductID" runat="server" Text='<%# Eval("ProductID") %>' />
                        
    </ItemTemplate>
                    
    </asp:TemplateField> 
                    
    <asp:BoundField DataField="ProductName" HeaderText="列7"/>  
                    
    <asp:ButtonField CommandName="Select" Text="Select" HeaderText="列8 按钮" />
                
    </Columns>
                
    <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
                
    <RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
                
    <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
                
    <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
                
    <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
                
    <AlternatingRowStyle BackColor="White" />
            
    </asp:GridView></div>
            
    <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="重新绑定数据" />
        
    </form>
    </body>
    </html>


    示例下载
  • 相关阅读:
    C#磁吸屏幕窗体类库
    准备
    我写的诗
    How to turn off a laptop keyboard
    How to tell which commit a tag points to in Git?
    Why should I care about lightweight vs. annotated tags?
    How to get rid of “would clobber existing tag”
    Facebook, Google and Twitter threaten to leave Hong Kong over privacy law changes
    The need for legislative reform on secrecy orders
    Can a foreign key be NULL and/or duplicate?
  • 原文地址:https://www.cnblogs.com/huige1004/p/1304417.html
Copyright © 2011-2022 走看看