Wes*_*s H 5 c# asp.net gridview webforms
我有一个gridview用于根据下拉列表中的选定值显示记录.
在gridview中,在代码后面添加了动态数量的绑定字段列,然后是模板字段中的下拉列表和第二个模板字段中的按钮.
问题是,当我点击按钮时,模板字段消失.
网格视图
<asp:UpdatePanel ID="upnlDetail" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="gvDetails" runat="server"
AutoGenerateColumns="false"
SkinID="gridviewGray"
CellPadding="3"
OnRowCommand="gvDetails_RowCommand"
OnRowDataBound="gvDetails_RowDataBound"
AllowSorting="true">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server"
AutoPostBack="true"
OnSelectedIndexChanged="ddlStatus_SelectedIndexChanged">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnSave" runat="server"
CommandName="Save"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
Text="Save" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
Run Code Online (Sandbox Code Playgroud)
代码背后
while (gvDetails.Columns.Count > 2) //Don't remove the rightmost columns
{
gvDetails.Columns.RemoveAt(0);
}
gvDetails.Columns.Insert(0, GridViewTools.CreateBoundField(
"Request.Amount", "Amount", "Money", 50));
gvDetails.Columns.Insert(0, GridViewTools.CreateBoundField(
"Request.CustomerName", "Customer", "comment", 200));
gvDetails.Columns.Insert(0, GridViewTools.CreateBoundField(
"Request.BillAccountFormatted", "Account", "text", 100));
gvDetails.Columns.Insert(0, GridViewTools.CreateBoundField(
"Request.Id", "Request", "int", 50));
gvDetails.DataSource = dt;
gvDetails.DataBind();
Run Code Online (Sandbox Code Playgroud)
方法GridViewTools.CreateBoundField是一个自定义方法,它设置我的默认boundfield属性并返回BoundField对象.
public static BoundField CreateBoundField(...){...}
Run Code Online (Sandbox Code Playgroud)
在测试中,gridview根据需要填充初始加载.但是,单击按钮时,RowCommand事件不会触发,两个模板字段都会消失.然后下一个gridview.RowDataBound事件抛出一个空对象错误,因为在该行中找不到下拉列表.
如果我删除添加绑定字段[Columns.Insert]的行,则在单击btnSave并且模板字段保持不变时,RowCommand将按预期触发.如果我再次添加一个绑定字段列,则RowCommand不会触发,模板字段也会消失.
有什么建议?为什么向gridview添加新列会使预先存在的按钮的RowCommand事件无效并使模板字段消失?
更新 我从网格视图声明中删除了模板字段,并将控件添加到绑定字段,但仍然得到相同的结果.显示初始加载,但一旦点击就消失.
我还查看了Page_Unload事件中的网格视图,它仍然包含该点的列,即使它们没有显示在屏幕上.在Page_Unload之后我可以捕获任何事件吗?
在代码后面构建所有内容。这不是一个偏好问题。请阅读动态 Web 服务器控件和视图状态
网页表格:
<asp:GridView ID="gvDetails" runat="server"
AutoGenerateColumns="false"
SkinID="gridviewGray"
CellPadding="3"
OnRowDataBound="OnRowDataBound"
OnRowCommand="gvDetails_RowCommand"
AllowSorting="true">
</asp:GridView>
Run Code Online (Sandbox Code Playgroud)
背后代码:
public class GridViewDropDownListTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
DropDownList ddlStatus = new DropDownList();
ddlStatus.ID = "ddlStatus";
ddlStatus.Items.Add(new ListItem("Status 1"));
ddlStatus.Items.Add(new ListItem("Status 2"));
ddlStatus.Items.Add(new ListItem("Status 3"));
ddlStatus.Items.Add(new ListItem("Status 4"));
ddlStatus.AutoPostBack = true;
ddlStatus.SelectedIndexChanged += ddlStatus_SelectedIndexChanged;
container.Controls.Add(ddlStatus);
}
public void ddlStatus_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
public class GridViewButtonTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
Button btnSave = new Button();
btnSave.ID = "btnSave";
btnSave.Text = "Save";
container.Controls.Add(btnSave);
}
}
public partial class Default : System.Web.UI.Page
{
object[] data = new[]
{
new { Amount = 12500.00, Account = "1234-567-89" },
new { Amount = 87000.00, Account = "0000-999-88" }
};
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BuildBoundFields();
}
BuildTemplateFields();
BindData();
}
protected void BuildBoundFields()
{
// Amount bound field
BoundField boundFieldAmount = new BoundField();
boundFieldAmount.DataField = "Amount";
boundFieldAmount.HeaderText = "Amount";
boundFieldAmount.SortExpression = "Amount";
boundFieldAmount.ItemStyle.Width = Unit.Pixel(100);
gvDetails.Columns.Add(boundFieldAmount);
// Account bould field
BoundField boundFieldAccount = new BoundField();
boundFieldAccount.DataField = "Account";
boundFieldAccount.HeaderText = "Account";
boundFieldAccount.SortExpression = "Account";
boundFieldAccount.ItemStyle.Width = Unit.Pixel(250);
gvDetails.Columns.Add(boundFieldAccount);
// ...
}
protected void BuildTemplateFields()
{
// Status template field
TemplateField statusTemplateField = new TemplateField();
statusTemplateField.ItemTemplate = new GridViewDropDownListTemplate();
gvDetails.Columns.Add(statusTemplateField);
// Save template field
TemplateField saveTemplateField = new TemplateField();
saveTemplateField.ItemTemplate = new GridViewButtonTemplate();
gvDetails.Columns.Add(saveTemplateField);
}
protected void BindData()
{
gvDetails.DataSource = data;
gvDetails.DataBind();
}
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Button btnSave = (Button)e.Row.FindControl("btnSave");
if (btnSave != null)
{
btnSave.CommandArgument = e.Row.RowIndex.ToString();
}
}
}
protected void gvDetails_RowCommand(object sender, GridViewCommandEventArgs e)
{
}
}
Run Code Online (Sandbox Code Playgroud)