gridview 中按钮的唯一 ID?
508 扫描标记了这样一个事实:我们在网格视图中的按钮具有相同的 id,我想知道如何解决这个问题。对于其中一些按钮,我们可以完全删除 id,它们似乎不会影响功能,但其他按钮实际上确实有后端代码,可以根据其他因素启用/禁用它们。这是前端代码:
<asp:TemplateField HeaderText="Accept" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button
ID="btnAccept"
runat="server"
Text="Accept Data"
CssClass="inherited"
CommandName="AcceptData"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:TemplateField>
这里是一些与此按钮相关的后端代码:
protected void gvDashboard_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int rowIndex = e.Row.RowIndex;
Button btnAccept = e.Row.FindControl(@"btnAccept") as Button;
Button btnRemove = e.Row.FindControl(@"btnRemove") as Button;
bool errors = (bool)gvDashboard.DataKeys[e.Row.RowIndex][@"Errors"];
string fileType = (string)gvDashboard.DataKeys[e.Row.RowIndex][@"FileType"];
string processingStatus = (string)gvDashboard.DataKeys[e.Row.RowIndex][@"ProcessingStatus"];
bool accepted = (bool)gvDashboard.DataKeys[e.Row.RowIndex][@"Accepted"];
int records = 0;
if (gvDashboard.DataKeys[e.Row.RowIndex][@"Records"] is System.DBNull)
{
int recordsColumnIndex = Utilities.GetColumnIndexByHeaderText(gvDashboard, @"Records");
e.Row.Cells[recordsColumnIndex].Text = @"0";
}
else
{
records = (int)gvDashboard.DataKeys[e.Row.RowIndex][@"Records"];
}
if (fileType == @"CN" || fileType == @"CP")
{
if ((DBNull.Value.Equals(gvDashboard.DataKeys[e.Row.RowIndex][@"ZipId"]))
|| ((int)gvDashboard.DataKeys[e.Row.RowIndex][@"ZipId"] == 0))
{
// CN or CP did not come from a zip file
if ((accepted))
{
btnAccept.Enabled = false;
btnRemove.Enabled = false;
}
}
else
{
btnAccept.Enabled = false;
btnRemove.Enabled = false;
}
}
if (accepted || processingStatus == @"I" || processingStatus == @"N")
{
btnAccept.Enabled = false;
}
}
}
catch (Exception ex)
{
DAL.ErrorLog(@"FilteredDashboard.gvDashboard_RowDataBound: Row: " + e.Row.RowIndex.ToString() + " " + ex.Message);
}
}
理想情况下,我希望能够将自动生成的数字添加到前端 ID 上,但随后考虑具有相同首字母缩写的 ID字符串(如“btnAccept”或“btnRemove”),无论其附加数字后缀如何。这可能吗?
A 508 Scan flagged the fact that we have identical id's for buttons in gridviews, and I'm wondering how to get around this. For some of these buttons we can remove the id's entirely and they don't seem to affect functionality, but others actually do have back-end code that enables/disables them based on other factors. Here's the front-end code:
<asp:TemplateField HeaderText="Accept" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button
ID="btnAccept"
runat="server"
Text="Accept Data"
CssClass="inherited"
CommandName="AcceptData"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:TemplateField>
And here is some of the backend code that pertains to this button:
protected void gvDashboard_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int rowIndex = e.Row.RowIndex;
Button btnAccept = e.Row.FindControl(@"btnAccept") as Button;
Button btnRemove = e.Row.FindControl(@"btnRemove") as Button;
bool errors = (bool)gvDashboard.DataKeys[e.Row.RowIndex][@"Errors"];
string fileType = (string)gvDashboard.DataKeys[e.Row.RowIndex][@"FileType"];
string processingStatus = (string)gvDashboard.DataKeys[e.Row.RowIndex][@"ProcessingStatus"];
bool accepted = (bool)gvDashboard.DataKeys[e.Row.RowIndex][@"Accepted"];
int records = 0;
if (gvDashboard.DataKeys[e.Row.RowIndex][@"Records"] is System.DBNull)
{
int recordsColumnIndex = Utilities.GetColumnIndexByHeaderText(gvDashboard, @"Records");
e.Row.Cells[recordsColumnIndex].Text = @"0";
}
else
{
records = (int)gvDashboard.DataKeys[e.Row.RowIndex][@"Records"];
}
if (fileType == @"CN" || fileType == @"CP")
{
if ((DBNull.Value.Equals(gvDashboard.DataKeys[e.Row.RowIndex][@"ZipId"]))
|| ((int)gvDashboard.DataKeys[e.Row.RowIndex][@"ZipId"] == 0))
{
// CN or CP did not come from a zip file
if ((accepted))
{
btnAccept.Enabled = false;
btnRemove.Enabled = false;
}
}
else
{
btnAccept.Enabled = false;
btnRemove.Enabled = false;
}
}
if (accepted || processingStatus == @"I" || processingStatus == @"N")
{
btnAccept.Enabled = false;
}
}
}
catch (Exception ex)
{
DAL.ErrorLog(@"FilteredDashboard.gvDashboard_RowDataBound: Row: " + e.Row.RowIndex.ToString() + " " + ex.Message);
}
}
Ideally I would like to be able to add on an autogenerated number onto the front-end ID, but then account for ID's with the same initial string (like 'btnAccept' or 'btnRemove') regarless of their additional numeric suffixes. Is that possible at all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ASP.NET Webforms 自动为每个控件生成按钮 ID,除非您将其设置为
如果您想确保 ID 是唯一的,请设置
因此问题可能来自其他地方,您可以在检查器中自行检查您的浏览器。
ASP.NET Webforms auto generates button IDs for each control, unless you set it to
If you'd like to make sure the IDs are unique, set
So the issue is probably coming from somewhere else, you can check it yourselves in the inspector of your browser.
正如 Zee 的回答所述 - 您可以使用每一行具有一个名称的查找控件 - 但是,每个行控件 - 包括按钮确实有自己的 id。
这个问题不应该存在——而且一般来说从来都不是问题。 GV 的每一行都会为每一行控件自动生成新的 id。但是,在生成新的“id”时,您可以在行数据绑定事件上使用带有控件名称的查找控件,而不会出现问题。
另外,您确实不需要保存/放入按钮命令参数的行索引。事实上,您还可以获得数据库主键 - 甚至不显示或在每行中显示 PK。
假设您设置了数据键(例如 PK“id”列),那么您可以对 gv 行上的按钮使用简单的按钮行单击事件。
您无法双击按钮来添加事件(因为它位于 GV 内),但您可以像这样使用 intel-sense:
只需键入 onclick= ,当您点击“=”时,您就会获得 intel 感知像这样:
因此,您可以选择创建新事件。
现在,在这个plane jane按钮事件中,您可以
因此,按钮背后的代码可以如下所示:
输出:
注意我如何使用datakeys设置。这对于安全性来说非常好,因为我不必在客户端公开所使用的数据库行 PK id。请注意我还如何获取当前的 GV 行索引 - 同样,无需将这些内容放入或弄乱实际的 gv 行中。因此,您甚至不需要使用命令参数。而且您也不需要使用 commandName。如果您希望触发 Gv selected 索引事件,则只需设置 CommandName。 (所以,您可能需要它),但作为一般规则,只需放入平面简按钮 - 连接事件,并像我一样使用“命名容器”获取当前行。然后你得到 GV 行,这样你就拥有了你需要的一切 - 包括行索引,甚至像我指出的那样使用数据键。
事实上,这意味着在大多数情况下我不会为内置的 GV 事件而烦恼 - 在大多数情况下它们不值得您花时间。
as noted in answer by Zee - you can use find control with the one name for each row - however, each row control - including buttons DOES get its own id.
This problem should not exist - and as a general rule never has been a issue. Each row of the GV will auto generate new id for each row of controls. However, while new "id" are generated, you can on the row data bind events use find control with the control name without issue.
Also, you really don't need to save/put in the row index for hte button command args. In fact, you can also get the database primary key - and NOT even display or have the PK displayed in each row.
Assuming you have datakeys set (say to PK "id" column), then you can then use a simple button row click event for a button on the gv row.
You can't double click on the button to add the event (since it inside the GV), but you can use intel-sense like this:
Just type in onclick= , and when you hit "=", the you get intel sense like this:
So, you can choose create new event.
Now, in this plane jane button event you can
So, the code behind the button can look like this:
Output:
Note how I used datakeys setting. This is REALLY nice for security, since I don't have to expose client side the database row PK id used. And note how I also picked up the current GV row index - again all without having to put or mess with that stuff in the actual gv row. So, you don't even need to use command Argument either. And you don't need to use commandName either. You ONLY need to set CommandName if you want the Gv selected index event to fire. (so, you might need it), but as a general rule, just drop in a plane jane button - wire up the event, and get the current row with "naming container" as I did. And then you get the GV row, and with that you have everything you need - including rowindex, and even use of datakeys as I pointed out.
In fact, this means for the most part I don't bother with the built in GV events - they are not worth your time in most cases.