C# 在 gridview 中使整行可点击
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/686240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Making an entire row clickable in a gridview
提问by Cameron Saliba
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 事件才能实现此目的?
回答by Keltex
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)检测点击并自己触发事件。或者,您必须创建用户选择的按钮或复选框。
回答by Ady Kemp
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。或者使用设置“e.NewSelectedIndex”的“SelectedIndexChanging”事件
回答by Andreas Grech
Check out this articleby 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# 中。
回答by Dan
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!)
基本上,您将不得不处理该行的点击事件(某些浏览器该行没有点击事件,因此您可能必须处理 tds 的点击事件...是时候投资 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 linkto an article along those lines
然后,您必须从 javascript 中使用行索引作为参数来触发回发。有关如何执行此操作,请参阅 encosia(ASP.Net - ajax 实现的绝佳站点)。这是指向这些内容的文章的链接
回答by MPritchard
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}",
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...
然后,您挂接到标准行命令事件...
回答by VDWWD
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.
这可以通过向LinkButton
GridView添加一个没有文本的虚拟对象和RowDataBound
. 页面上需要 LinkButton 以避免Invalid postback or callback argument
错误。将可见性设置为false
也会导致此错误。
The LinkButton also has a CommandArgument
with the current row number and a OnCommand
event to handle the actual clicking.
LinkButton 也有一个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.
还有命令方法,您可以在其中从 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
}