【问题标题】:Making an entire row clickable in a gridview在gridview中使整行可点击
【发布时间】:2023-04-08 16:54:01
【问题描述】:

我有一个gridview,我需要在点击一行时触发一个事件。

我需要绑定一个现有的 GridView 事件来实现这一点吗?

【问题讨论】:

标签: c# asp.net gridview


【解决方案1】:

这是我之前准备的:

public class RowClickableGridView : GridView { public Style HoverRowStyle { get { return ViewState["HoverRowStyle"] as Style; } set { ViewState["HoverRowStyle"] = value; } } public bool EnableRowClickSelection { get { return ViewState["EnableRowClickSelection"] as bool? ?? true; } set { ViewState["EnableRowClickSelection"] = value; } } public string RowClickCommand { get { return ViewState["RowClickCommand"] as string ?? "Select"; } set { ViewState["RowClickCommand"] = value; } } public string RowToolTip { get { if (!RowToolTipSet) return string.Format("Click to {0} row", RowClickCommand.ToLowerInvariant()); return ViewState["RowToolTip"] as string; } set { ViewState["RowToolTip"] = value; RowToolTipSet = true; } } private bool RowToolTipSet { get { return ViewState["RowToolTipSet"] as bool? ?? false; } set { ViewState["RowToolTipSet"] = value; } } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); foreach (GridViewRow row in Rows) { if (row.RowType != DataControlRowType.DataRow) continue; if (EnableRowClickSelection && row.RowIndex != SelectedIndex && row.RowIndex != EditIndex) { if (string.IsNullOrEmpty(row.ToolTip)) row.ToolTip = RowToolTip; row.Style[HtmlTextWriterStyle.Cursor] = "pointer"; PostBackOptions postBackOptions = new PostBackOptions(this, string.Format("{0}${1}", RowClickCommand, row.RowIndex)); postBackOptions.PerformValidation = true; row.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(postBackOptions); foreach (TableCell cell in row.Cells) { foreach (Control control in cell.Controls) { const string clientClick = "event.cancelBubble = true;{0}"; WebControl webControl = control as WebControl; if (webControl == null) continue; webControl.Style[HtmlTextWriterStyle.Cursor] = "Auto"; Button button = webControl as Button; if (button != null) { button.OnClientClick = string.Format(clientClick, button.OnClientClick); continue; } ImageButton imageButton = webControl as ImageButton; if (imageButton != null) { imageButton.OnClientClick = string.Format(clientClick, imageButton.OnClientClick); continue; } LinkButton linkButton = webControl as LinkButton; if (linkButton != null) { linkButton.OnClientClick = string.Format(clientClick, linkButton.OnClientClick); continue; } webControl.Attributes["onclick"] = string.Format(clientClick, string.Empty); } } } if (HoverRowStyle == null) continue; if (row.RowIndex != SelectedIndex && row.RowIndex != EditIndex) { row.Attributes["onmouseover"] = string.Format("this.className='{0}';", HoverRowStyle.CssClass); row.Attributes["onmouseout"] = string.Format("this.className='{0}';", row.RowIndex%2 == 0 ? RowStyle.CssClass : AlternatingRowStyle.CssClass); } else { row.Attributes.Remove("onmouseover"); row.Attributes.Remove("onmouseout"); } } } protected override void Render(HtmlTextWriter writer) { base.Render(writer); foreach (GridViewRow row in Rows) { if (row.RowType == DataControlRowType.DataRow) { Page.ClientScript.RegisterForEventValidation(row.ClientID); } } } }

然后你钩入标准的行命令事件...

【讨论】:

  • @MPritch:你能帮我如何使用这个类吗?
【解决方案2】:

为了实现这一点,需要一些 javascript 编程。

基本上,您将不得不处理该行的单击事件(某些浏览器该行没有单击事件,因此您可能必须处理 tds 的单击事件...时间投资于 ajax框架!)

然后,您将不得不从 javascript 中以行索引作为参数来触发回发。请参阅 encosia(一个很棒的 ASP.Net - ajax 实现站点)了解如何做到这一点。这是一篇文章的link

【讨论】:

    【解决方案3】:

    这可以通过在 GridView 中添加一个没有文本的虚拟 LinkButton 并在 RowDataBound 中添加一些代码来轻松完成。 页面上需要 LinkBut​​ton 以避免出现Invalid postback or callback argument 错误。将可见性设置为false 也会导致此错误。

    LinkBut​​ton 还有一个带有当前行号的CommandArgument 和一个用于处理实际点击的OnCommand 事件。

    <asp:TemplateField>
        <ItemTemplate>
            <asp:LinkButton ID="LinkButton1" runat="server" CommandArgument='<%# Container.DataItemIndex %>' OnCommand="LinkButton1_Command"></asp:LinkButton>
        </ItemTemplate>
    </asp:TemplateField>
    

    OnRowDataBound 方法

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        //check if the row is a datarow
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            //find the linkbutton with findcontrol and cast it back to one
            LinkButton lb = e.Row.FindControl("LinkButton1") as LinkButton;
    
            //create the correct postback event with the UniqueID property of the linkbutton
            string href = "javascript:__doPostBack('" + lb.UniqueID + "','')";
    
            //add the onclick event with the correct href to the row
            e.Row.Attributes.Add("onclick", href);
    
            //to make it visible to the user that the row can be clicked
            e.Row.Attributes.Add("style", "cursor:pointer;");
        }
    }
    

    还有命令方法,您可以在其中从 LinkBut​​ton 获取 CommandArgument 并用它做各种巧妙的事情。

    protected void LinkButton1_Command(object sender, CommandEventArgs e)
    {
        //the row index of the clicked row from the grid if needed
        int rowIndex = Convert.ToInt32(e.CommandArgument);
    
        //do stuff
    }
    

    【讨论】:

      【解决方案4】:

      不存在处理整行点击的现有事件。最好的办法是让一些 javascript(可能通过 ASP.NET Ajax)检测点击并自己触发事件。或者,您必须创建用户选择的按钮或复选框。

      【讨论】:

        【解决方案5】:

        您需要处理“SelectedIndexChanged”事件,然后您可以在网格中查询 .SelectedRow。 Alternativley 使用设置“e.NewSelectedIndex”的“SelectedIndexChanging”事件

        【讨论】:

        • 但是只有在绑定 GridView 时才会触发该事件,不是吗?不是当用户点击一行时
        【解决方案6】:

        查看 Teemu 的 this article,他在其中解释了单击 Gridview 中的一行并引发 RowClicked 事件。

        这里是代码的摘录:

        Protected Overrides Sub RaisePostBackEvent(ByVal eventArgument As String)
                    If eventArgument.StartsWith("rc") Then
                        Dim index As Integer = Int32.Parse(eventArgument.Substring(2))
                        Dim args As New GridViewRowClickedEventArgs(Me.Rows(index))
                        OnRowClicked(args)
                    Else
                        MyBase.RaisePostBackEvent(eventArgument)
                    End If
        
                End Sub
        
         Public Class GridViewRowClickedEventArgs
                Inherits EventArgs
        
                Private _row As GridViewRow
                Public Sub New(ByVal row As GridViewRow)
                    _row = row
                End Sub
                Public ReadOnly Property Row() As GridViewRow
                    Get
                        Return _row
                    End Get
                End Property
            End Class
        

        顺便说一句,它是在 VB 而不是 C# 中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-03
          • 2019-07-25
          • 1970-01-01
          • 2016-08-03
          • 1970-01-01
          • 1970-01-01
          • 2014-11-16
          相关资源
          最近更新 更多