在gridview中使整行可单击

时间:2023-01-17 13:43:55

I have a gridview and I need to make an event fire when a row is clicked.

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

Is there an existing GridView event I need to bind to to make this happen?

是否存在我需要绑定的现有GridView事件才能实现此目的?

6 个解决方案

#1


16  

Here's something I prepared earlier:

这是我之前准备的东西:


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);
                }
            }
        }
    }

You then hook into the standard row command events...

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

#2


1  

Some javascript programming will be required in order to make this happen.

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

Basically you are going to have to handle the click event for the row(is some browsers the row does not have a click event so you might have to handle the click event of the tds... time to invest in an ajax framework!)

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

You will then from javascript have to fire a postback with the row index as a parameter. See encosia(a great site for ASP.Net - ajax implementations) on how to do that. Here is a link to an article along those lines

然后,您将从javascript必须以行索引作为参数触发回发。有关如何执行此操作,请参阅encosia(ASP.Net的一个很棒的站点 - ajax实现)。以下是这些文章的链接

#3


0  

There is no existing event to handle an entire row click. Your best bet is to have some javascript (maybe via ASP.NET Ajax) detect the click and fire the event yourself. Alternatively you would have to create a button or checkbox that the user selects.

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

#4


0  

You need to handle the "SelectedIndexChanged" event, you can then query the grid for the .SelectedRow. Alternativley use the "SelectedIndexChanging" event which sets "e.NewSelectedIndex"

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

#5


0  

Check out this article by Teemu, in where he explains about clicking a row in Gridview and throw the RowClicked event.

查看Teemu撰写的这篇文章,在那里他解释了如何在Gridview中单击一行并抛出RowClicked事件。

Here is a excerpt of the code:

以下是代码的摘录:

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

Btw, it's in VB not C# though.

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

#6


0  

This can be done easily by adding a dummy LinkButton with no Text to the GridView and some code in the RowDataBound. The LinkButton is needed on the page to avoid the Invalid postback or callback argument error. Setting the visibility to false will also cause this error.

这可以通过向GridView添加一个没有Text的虚拟LinkBut​​ton和RowDataBound中的一些代码来轻松完成。页面上需要LinkBut​​ton以避免无效的回发或回调参数错误。将可见性设置为false也会导致此错误。

The LinkButton also has a CommandArgument with the current row number and a OnCommand event to handle the actual clicking.

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

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

The OnRowDataBound method

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;");
    }
}

And the Command Method where you can get the CommandArgument from the LinkButton and do all sorts of neat things with it.

还有Command方法,你可以从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
}

#1


16  

Here's something I prepared earlier:

这是我之前准备的东西:


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);
                }
            }
        }
    }

You then hook into the standard row command events...

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

#2


1  

Some javascript programming will be required in order to make this happen.

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

Basically you are going to have to handle the click event for the row(is some browsers the row does not have a click event so you might have to handle the click event of the tds... time to invest in an ajax framework!)

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

You will then from javascript have to fire a postback with the row index as a parameter. See encosia(a great site for ASP.Net - ajax implementations) on how to do that. Here is a link to an article along those lines

然后,您将从javascript必须以行索引作为参数触发回发。有关如何执行此操作,请参阅encosia(ASP.Net的一个很棒的站点 - ajax实现)。以下是这些文章的链接

#3


0  

There is no existing event to handle an entire row click. Your best bet is to have some javascript (maybe via ASP.NET Ajax) detect the click and fire the event yourself. Alternatively you would have to create a button or checkbox that the user selects.

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

#4


0  

You need to handle the "SelectedIndexChanged" event, you can then query the grid for the .SelectedRow. Alternativley use the "SelectedIndexChanging" event which sets "e.NewSelectedIndex"

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

#5


0  

Check out this article by Teemu, in where he explains about clicking a row in Gridview and throw the RowClicked event.

查看Teemu撰写的这篇文章,在那里他解释了如何在Gridview中单击一行并抛出RowClicked事件。

Here is a excerpt of the code:

以下是代码的摘录:

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

Btw, it's in VB not C# though.

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

#6


0  

This can be done easily by adding a dummy LinkButton with no Text to the GridView and some code in the RowDataBound. The LinkButton is needed on the page to avoid the Invalid postback or callback argument error. Setting the visibility to false will also cause this error.

这可以通过向GridView添加一个没有Text的虚拟LinkBut​​ton和RowDataBound中的一些代码来轻松完成。页面上需要LinkBut​​ton以避免无效的回发或回调参数错误。将可见性设置为false也会导致此错误。

The LinkButton also has a CommandArgument with the current row number and a OnCommand event to handle the actual clicking.

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

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

The OnRowDataBound method

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;");
    }
}

And the Command Method where you can get the CommandArgument from the LinkButton and do all sorts of neat things with it.

还有Command方法,你可以从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
}