【发布时间】:2013-03-04 11:09:45
【问题描述】:
在询问之前我已经进行了一些搜索,虽然 this post 很接近,但它不适用于我的场景。
我发现我的模板字段中的“删除”按钮似乎触发了,但点击事件没有触发。然而,当您第二次单击该按钮时,它会按预期工作。
因此,分解代码后,我使用 `SqlDataSource 将我的数据绑定到 GridView。
我的页面加载事件开始如下:
if (!Page.IsPostBack)
{
externalUserDataSource.ConnectionString = "some connection string";
}
我的数据源如下:
<asp:SqlDataSource ID="externalUserDataSource" runat="server"
ConflictDetection="CompareAllValues" SelectCommand="uspGetExternalUsersByTeam"
SelectCommandType="StoredProcedure" ProviderName="System.Data.SqlClient">
<SelectParameters>
<asp:SessionParameter Name="TeamID" SessionField="TeamID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
这是我的GridView 标记:
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False"
BackColor="White" BorderColor="#3366CC" BorderStyle="None" BorderWidth="1px"
CellPadding="4" DataKeyNames="LoginID" DataSourceID="externalUserDataSource"
EnableModelValidation="True" OnRowDataBound="GridViewRowDataBound" TabIndex="3">
<HeaderStyle BackColor="#003399" Font-Bold="True" ForeColor="White" />
<FooterStyle BackColor="#99CCCC" ForeColor="#003399" />
<PagerStyle BackColor="#99CCCC" ForeColor="#003399" HorizontalAlign="Left" />
<RowStyle BackColor="LightGoldenrodYellow" />
<SelectedRowStyle BackColor="#009999" Font-Bold="True" ForeColor="#CCFF99" />
<Columns>
<asp:BoundField DataField="RowID" HeaderText="Row ID" ReadOnly="True"
SortExpression="RowID" Visible="False" />
<asp:BoundField DataField="LoginID" HeaderText="Login ID" ReadOnly="True"
SortExpression="LoginID" Visible="False" />
<asp:BoundField DataField="EmailAddress" HeaderText="Email Address"
ItemStyle-VerticalAlign="Bottom" ReadOnly="True" SortExpression="AssociateName"/>
<asp:BoundField DataField="TeamID" HeaderText="Team ID" ReadOnly="True"
SortExpression="TeamID" Visible="False" />
<asp:CheckBoxField DataField="HasFIAccess"
HeaderText="Has Access to<br />Funding<br/>Illustrator"
ItemStyle-HorizontalAlign="Center" ItemStyle-VerticalAlign="Bottom"
ReadOnly="True"/>
<asp:CheckBoxField DataField="HasALTAccess"
HeaderText="Has Access to<br />Asset Liability<br/>Tracker"
ItemStyle-HorizontalAlign="Center" ItemStyle-VerticalAlign="Bottom"
ReadOnly="True"/>
<asp:CheckBoxField DataField="HasFIAAccess"
HeaderText="Has Access to<br />Funding<br/>Illustrator App"
ItemStyle-HorizontalAlign="Center" ItemStyle-VerticalAlign="Bottom"
ReadOnly="True"/>
<asp:TemplateField>
<ItemTemplate>
<asp:Button runat="server" CssClass="additionsRow" ID="btnDeleteExternalUser" OnClick="DeleteExtUserButtonClick"
CausesValidation="False" Text="Delete"
CommandArgument='<%#Eval("TeamID") + "," + Eval("LoginID") + "," + Eval("EmailAddress") + "," + Eval("HasALTAccess")%>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
因此,您可以看到我在事件中使用的按钮中传递了一些信息,以确保删除正确的数据(这就是为什么我不能使用ButtonField,如上面的链接中所建议的那样) .
谜题的最后一部分是GridView的数据绑定事件:
protected void GridViewRowDataBound(object sender,
GridViewRowEventArgs e)
{
// if rowtype is not data row...
if (e.Row.RowType != DataControlRowType.DataRow)
{
// exit with no further processing...
return;
}
// get the ID for the selected record...
var selectedId = DataBinder.Eval(e.Row.DataItem, "RowID").ToString();
// create unique row ID...
e.Row.ID = string.Format("ExtUserRow{0}", selectedId);
// find the button delete for the selected row...
var deleteButton = (Button)e.Row.FindControl("btnDeleteExtUser");
// get the email address for the selected record...
var selectedUser = DataBinder.Eval(e.Row.DataItem, "EmailAddress").ToString();
// define the message text...
var messageText = string.Format("OK to delete {0}?",
selectedUser.Replace("'", "\\'"));
// add attribute to row delete action...
this.AddConfirmMessage(deleteButton, messageText);
}
AddConfirmMessage 只是简单地将 onclick 属性分配给控件以确保用户必须确认删除。
现在,在每种情况下都会弹出消息“OK to delete abc@xyz.com?”,但如前所述,分配给“delete”按钮的事件直到按钮被第二次点击。
奇怪的是,我从另一个页面获取了这段代码并进行了相应的修改,尽管那里没有这个问题:
protected void DeleteExtUserButtonClick(object sender,
EventArgs e)
{
// get the buton which was clicked...
var button = (Button)sender;
// break the delimited array up...
string[] argumentArray = button.CommandArgument.Split(',');
// store the items from the array...
string teamId = argumentArray[0];
string loginId = argumentArray[1];
string emailAddress = argumentArray[2];
string hasAltAccess = argumentArray[3];
using (var conn = new SqlConnection(Utils.GetConnectionString()))
{
// create database command...
using (var cmd = new SqlCommand())
{
// set the command type...
cmd.CommandType = CommandType.StoredProcedure;
// set the name of the stored procedure to call...
cmd.CommandText = "uspDeleteExternalUser";
// create and add parameter to the collection...
cmd.Parameters.Add(new SqlParameter("@TeamId", SqlDbType.Int));
// assign the search value to the parameter...
cmd.Parameters["@TeamId"].Value = teamId;
// create and add parameter to the collection...
cmd.Parameters.Add(new SqlParameter("@LoginId", SqlDbType.VarChar, 50));
// assign the search value to the parameter...
cmd.Parameters["@LoginId"].Value = loginId;
// set the command connection...
cmd.Connection = conn;
// open the connection...
conn.Open();
// perform deletion of user...
cmd.ExecuteNonQuery();
}
}
// bind control to refresh content...
ExtUsersGrid.DataBind();
}
我是否遗漏了一些明显的东西?如果有更好的方法,我很乐意修改。
编辑 1:根据下面的讨论,我修改了以下内容:
- 删除了
ButtonItem的Onclick事件属性; - 按照以下建议设置
CommandName和CommandArgument,并更新DataKeyNames以使用数据中唯一的ID RowID; - 为
GridView分配了RowCommand事件; - 将删除代码分配给
RowCommand事件。
进行这些更改后,它仍然会在第二次点击时触发行事件代码。
编辑 2:仅供参考 - 我现在删除了 SqlDataSource 和相关的代码/引用,并创建了一个填充数据集的过程,该过程在 Page_Load 上调用(在!Page.IsPostBack 括号)。我开始在下面进行更改以使用 RowCommand 事件,但它们仍然导致相同的问题(即该按钮只会在第二次单击时触发)。因为使用RowCommand 意味着将BoundFields 转换为ItemTemplates,所以我回到了按钮单击事件,因为毫无意义地进行所有这些更改似乎毫无意义。如果其他人可以帮助我理解为什么它只在第二次点击时触发,将不胜感激。
【问题讨论】:
-
您似乎没有像示例中那样向 deleteButton 添加事件处理程序。
-
是的,抱歉,我注意到了这一点并更新了我的代码 - 我试图在代码中添加事件,但在发布我的问题之前忘记将其添加回来。代码现在是最新的。
-
如果我也分享我的删除按钮事件代码可能会很有用,所以会在下面添加一个答案。
-
那么你在哪里添加事件处理程序?也许我在这里挑剔,但似乎您仍然没有将 DeleteExtUserButtonClick 添加到按钮。
-
在 Button 字段中的代码是
OnClick="DeleteExtUserButtonClick"但实际上,这已经过去了,因为我已经通过启动 RowCommand 事件来使用 Praveen 建议的方法,将网格填充为第一个回发,但我仍然有同样的问题。它与哪个按钮无关,所以我可以在第 1 行删除,你会看到看起来像回发但没有触发代码的内容,然后在第 2 行单击删除,你会得到相同的结果。直到第二次单击,RowCommand 的代码才会触发。所以虽然我有更好的代码,但它仍然给我同样的问题。
标签: c# asp.net gridview templatefield