如何在没有选择按钮的情况下在 GridView 中实现全行选择?

Posted

技术标签:

【中文标题】如何在没有选择按钮的情况下在 GridView 中实现全行选择?【英文标题】:How to implement full row selecting in GridView without select button? 【发布时间】:2011-09-09 04:23:07 【问题描述】:

我正在实现一项功能,当用户按下 GridView 中行中的任何点时,将选择该行而不是选择按钮。

为了实现这一点,我使用了以下代码:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)

    if (e.Row.RowType == DataControlRowType.DataRow)
    
        // Set the hand mouse cursor for the selected row.
        e.Row.Attributes.Add("OnMouseOver", "this.style.cursor = 'hand';");

        // The seelctButton exists for ensuring the selection functionality
        // and bind it with the appropriate event hanlder.
        LinkButton selectButton = new LinkButton()
        
            CommandName = "Select",
            Text = e.Row.Cells[0].Text
        ;

        e.Row.Cells[0].Controls.Add(selectButton);
        e.Row.Attributes["OnClick"] =
             Page.ClientScript.GetPostBackClientHyperlink(selectButton, "");
    

上面的代码有以下问题:

仅当我将页面的EnableEventValidation 设置为false 时,此方法才能正常工作。 SelectedIndexChanged 仅在页面的Page_Load 中调用Grid.DataBind() 时才会触发(在每个回发中)。

我做错了吗?有没有更好的实现方式?


编辑:EnableEventValidation设置为true时,会出现如下错误:

回发或回调参数无效。使用配置或页面中的 启用事件验证。出于安全目的,此功能验证回发或回调事件的参数是否源自最初呈现它们的服务器控件。如果数据有效且符合预期,请使用 ClientScriptManager.RegisterForEventValidation 方法注册回发或回调数据以进行验证。

【问题讨论】:

【参考方案1】:

您必须在每次回发时添加它,而不仅仅是在数据绑定中。因此,您应该使用 GridView 的RowCreated-Event。

例如

(C#):

protected void GridView1_RowCreated(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)

    if (e.Row.RowType == DataControlRowType.DataRow) 
        e.Row.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
        e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
        e.Row.ToolTip = "Click to select row";
        e.Row.Attributes["onclick"] = this.Page.ClientScript.GetPostBackClientHyperlink(this.GridView1, "Select$" + e.Row.RowIndex);
    

(VB.Net):

Private Sub GridView1_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowCreated
    If e.Row.RowType = DataControlRowType.DataRow Then
        e.Row.Attributes("onmouseover") = "this.style.cursor='pointer';this.style.textDecoration='underline';"
        e.Row.Attributes("onmouseout") = "this.style.textDecoration='none';"
        e.Row.ToolTip = "Click to select row"
        e.Row.Attributes("onclick") = Me.Page.ClientScript.GetPostBackClientHyperlink(Me.GridView1, "Select$" & e.Row.RowIndex)
    End If
End Sub

【讨论】:

这并不能解决将EnableEventValidation设置为false的问题。 @Homam:您是否使用过我的代码,但仍然收到“无效的回发/回调参数”错误?我无法在我的项目中重现此错误,但这可能还有另一个原因。我现在没有时间进一步调查。您可以使用ClientScriptManager.RegisterForEventValidation 来避免它。也许this link 有帮助。 用什么语言来描述风格?我尝试过使用 CSS,但这似乎不起作用。例如它不是背景颜色,它的背景颜色。【参考方案2】:

您可以在Render() 上执行此操作,而不是在RowCreated 上执行此操作。这样你就可以在registerForEventValidation 上使用GetPostBackClientHyperlink 的重载和true 并避免“无效的回发/回调参数”错误。

类似这样的:

protected override void Render(htmlTextWriter writer)
    
      foreach (GridViewRow r in GridView1.Rows)
      
        if (r.RowType == DataControlRowType.DataRow)
        
          r.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
          r.Attributes["onmouseout"] = "this.style.textDecoration='none';";
          r.ToolTip = "Click to select row";
          r.Attributes["onclick"] = this.Page.ClientScript.GetPostBackClientHyperlink(this.GridView1, "Select$" + r.RowIndex,true);

        
      

      base.Render(writer);
    

【讨论】:

这也解决了我的问题。互联网上的所有其他帖子都在告诉您禁用EnableEventValidation,这会使您的网站容易受到注入攻击,只有这一个才是真正的答案。【参考方案3】:
<style type="text/css">
    .hiddenColumn
    
        display: none;
    

    .rowGrid
    
        cursor: pointer;
    
</style>

<asp:GridView runat="server" ID="GridView1" AutoGenerateColumns="true" >
            <RowStyle CssClass="rowGrid" />
            <Columns>
                <asp:CommandField ButtonType="Button" ShowSelectButton="true" HeaderStyle-CssClass="hiddenColumn"
                    ItemStyle-CssClass="hiddenColumn" FooterStyle-CssClass="hiddenColumn" />
            </Columns>
        </asp:GridView>

<script type="text/javascript">
        $(function () 
            $("#<%= GridView1.ClientID %> tr.rowGrid")
            .live("click", function (event) 
                $(this).find("input[type='button'][value='Select']").click();
            );

            $("#<%= GridView1.ClientID %> input[type='button'][value='Select']")
                .live("click", function (event) 
                    event.stopPropagation();
                );

        );
    </script>

【讨论】:

【参考方案4】:

试试这个 在网格中添加 OnSelectedIndexChanged 事件

   OnSelectedIndexChanged="Grid_SelectedIndexChanged"

然后是后面的代码

 protected void Grid_SelectedIndexChanged(object sender, EventArgs e)

    GridViewRow row = gvSummary.SelectedRow;
    //Int32 myvalue= Convert.ToInt32(row.Attributes["ColumnName"].ToString());
    

并设置 EnableViewState="false" 但是在这里你必须执行你已经在你的代码中完成的另外两件事意味着 将 EnableEventValidation 设置为 false 并在页面 Load 上设置 Grid Databinding..

【讨论】:

【参考方案5】:

尝试在 ASPX 代码中使用 &lt;tr&gt; 周围的 &lt;asp:LinkButton&gt;,设置 LinkBut​​ton 的 CommandName='Select' 并在项目命令事件中,处理此命令并设置所选行的样式!

【讨论】:

你确定在 td 和 tr 之间有一个链接按钮会生成一个有效的完全兼容的 HTML 吗? @Davide Piras:问题中没有提到符合标准的 HTML 作为要求!如果这是一个要求,那么不要接受解决方案!我发现了一些可能性! 我不同意,我没有投票给你,也不会,但即使在原始帖子中没有提到,来吧我们在 2011 年夏天(几乎),让我们只提供跨浏览器和完全合规的答案:) ;-) @Davide Piras:我不介意反对票!关于标准合规性,我完全同意你的看法!但是,我只是想帮忙!不多不少!我遇到了与@Homan 类似的情况,但是我必须最早在生产服务器上使用它。因此,无法负担标准合规性! ;-) 想一想,这个人也处于类似的情况,并且会从我当时所做的快速修复中受益。干杯! :-)

以上是关于如何在没有选择按钮的情况下在 GridView 中实现全行选择?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有 ef 的情况下在 MVC5 中使用参数进行搜索

如何在没有文本框的情况下在 Selenium 中上传文件

如何在没有加入的情况下在 BigQuery 的同一个表中选择匹配项

如何在没有 Artisan 的情况下在 Xampp 上运行 laravel

如何在没有静态文本的情况下在 XCTest 中快速测试 Webview 是不是加载

如何在没有外部库的情况下在 React 中播放/暂停视频?