【发布时间】:2023-04-08 16:54:01
【问题描述】:
我有一个gridview,我需要在点击一行时触发一个事件。
我需要绑定一个现有的 GridView 事件来实现这一点吗?
【问题讨论】:
我有一个gridview,我需要在点击一行时触发一个事件。
我需要绑定一个现有的 GridView 事件来实现这一点吗?
【问题讨论】:
这是我之前准备的:
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);
}
}
}
}
然后你钩入标准的行命令事件...
【讨论】:
为了实现这一点,需要一些 javascript 编程。
基本上,您将不得不处理该行的单击事件(某些浏览器该行没有单击事件,因此您可能必须处理 tds 的单击事件...时间投资于 ajax框架!)
然后,您将不得不从 javascript 中以行索引作为参数来触发回发。请参阅 encosia(一个很棒的 ASP.Net - ajax 实现站点)了解如何做到这一点。这是一篇文章的link
【讨论】:
这可以通过在 GridView 中添加一个没有文本的虚拟 LinkButton 并在 RowDataBound 中添加一些代码来轻松完成。
页面上需要 LinkButton 以避免出现Invalid postback or callback argument 错误。将可见性设置为false 也会导致此错误。
LinkButton 还有一个带有当前行号的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;");
}
}
还有命令方法,您可以在其中从 LinkButton 获取 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
}
【讨论】:
不存在处理整行点击的现有事件。最好的办法是让一些 javascript(可能通过 ASP.NET Ajax)检测点击并自己触发事件。或者,您必须创建用户选择的按钮或复选框。
【讨论】:
您需要处理“SelectedIndexChanged”事件,然后您可以在网格中查询 .SelectedRow。 Alternativley 使用设置“e.NewSelectedIndex”的“SelectedIndexChanging”事件
【讨论】:
查看 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# 中。
【讨论】: