在 Formview 中嵌套 Gridview 会破坏插入代码隐藏上下文
Nesting Gridview inside Formview breaks insert codebehind context
我的 FormView 页面中有几个 GridView,我想在 Gridview 的 FooterRow 中插入一行。布局和一切都很好。但是,当我为 Insert 命令构建代码隐藏时,我 运行 遇到了上下文问题。如果我将 GridView 移到 FormView 标记之外,上下文错误会立即清除。
网格视图标记
<asp:GridView ID="gvBFMats" runat="server" ShowFooter="True" AutoGenerateColumns="False" DataKeyNames="MaterialID" DataSourceID="BFMatsSQL" OnRowCommand="gvBFMats_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Commands" ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="ButtonUpdate" runat="server" CausesValidation="True" CommandName="Update" Text="Update"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="ButtonEdit" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit"></asp:LinkButton>
<asp:LinkButton ID="ButtonDelete" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete"></asp:LinkButton>
</ItemTemplate>
<FooterTemplate>
<asp:LinkButton ID="ButtonAdd" runat="server" CommandName="Insert" Text="Add to Table" />
</FooterTemplate>
...
插入命令代码隐藏
protected void gvBFMats_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Insert" && Page.IsValid)
{
BFMatsSQL.Insert();
}
}
protected void BFMatsSQL_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
DropDownList ddlNewMfr =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewMfr");
DropDownList ddlNewThickness =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewThickness");
DropDownList ddlNewCore =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewCore");
DropDownList ddlNewSize =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewSize");
TextBox txtNewColor =
(TextBox)gvBFMats.FooterRow.FindControl("txtNewColor");
TextBox txtNewQty =
(TextBox)gvBFMats.FooterRow.FindControl("txtNewQty");
DropDownList ddlNewFinish =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewFinish");
TextBox txtNewExtra =
(TextBox)gvBFMats.FooterRow.FindControl("txtNewExtra");
// Set the SQLDataSource's InsertParameters values
e.InputParameters["MatManufacturerID"] =
Convert.ToInt32(ddlNewMfr.SelectedValue);
e.InputParameters["MatThicknessID"] =
Convert.ToInt32(ddlNewThickness.SelectedValue);
e.InputParameters["MatCoreID"] =
Convert.ToInt32(ddlNewCore.SelectedValue);
e.InputParameters["MatSizeID"] =
Convert.ToInt32(ddlNewSize.SelectedValue);
e.InputParameters["MatFinishPrePostID"] =
Convert.ToInt32(ddlNewFinish.SelectedValue);
string strNewColor = null;
if (!string.IsNullOrEmpty(txtNewColor.Text))
strNewColor = txtNewColor.Text;
e.InputParameters["MatFinishColor"] = strNewColor;
int? intNewQty = null;
if (!string.IsNullOrEmpty(txtNewQty.Text))
intNewQty = Convert.ToInt32(txtNewQty.Text);
e.InputParameters["MatQty"] = intNewQty;
string strNewExtra = null;
if (!string.IsNullOrEmpty(txtNewExtra.Text))
strNewExtra = txtNewExtra.Text;
e.InputParameters["MatNumExtraSheets"] = strNewExtra;
}
具体来说,我在 (Control)gvBFMats.FooterRow.FindControl("Control ID");
中的 gvBFMats 下看到了红色的波浪线,上面写着 "The name 'gvBFMats' does not exist in the current context." 我只是猜测它不喜欢在嵌套在一个窗体视图模板。有没有办法以编程方式传递此上下文?
你说得对,它无法识别名称 gvBFMats
,因为它嵌入在模板中。只有 "top-level",非嵌入式控件将在代码隐藏中被视为已明确声明。在模板中声明的控件不会。编译器无法识别这些名称。
这是有原因的。假设您在 ItemTemplates
之一中有一个名为 TextBox1
的控件,用于重复控件。你绑定它。您页面的控件树现在有许多 ID 为 TextBox1
的控件。如果你想引用 TextBox1
,它怎么知道你指的是哪一个?
所以。在你的情况下你能做什么?好吧,BFMatsSQL_Inserting
和 gvBFMats_RowCommand
都是事件处理程序,因此您不能更改它们的签名。
但是,您可以使用属于同一个 class 的它们,并使用模块级变量来保存对 gvBFMats
的引用。像这样:
private GridView gvBFMats;
protected void gvBFMats_RowCommand(object sender, GridViewCommandEventArgs e)
{
gvBFMats = [your form view].Row.FindControl("gvBFMats") as GridView;
if (e.CommandName == "Insert" && Page.IsValid)
{
BFMatsSQL.Insert();
}
}
现在,BFMatsSQL_Inserting
可以引用 gvBFMats
,它应该有一个值。
我的 FormView 页面中有几个 GridView,我想在 Gridview 的 FooterRow 中插入一行。布局和一切都很好。但是,当我为 Insert 命令构建代码隐藏时,我 运行 遇到了上下文问题。如果我将 GridView 移到 FormView 标记之外,上下文错误会立即清除。
网格视图标记
<asp:GridView ID="gvBFMats" runat="server" ShowFooter="True" AutoGenerateColumns="False" DataKeyNames="MaterialID" DataSourceID="BFMatsSQL" OnRowCommand="gvBFMats_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Commands" ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="ButtonUpdate" runat="server" CausesValidation="True" CommandName="Update" Text="Update"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="ButtonEdit" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit"></asp:LinkButton>
<asp:LinkButton ID="ButtonDelete" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete"></asp:LinkButton>
</ItemTemplate>
<FooterTemplate>
<asp:LinkButton ID="ButtonAdd" runat="server" CommandName="Insert" Text="Add to Table" />
</FooterTemplate>
...
插入命令代码隐藏
protected void gvBFMats_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Insert" && Page.IsValid)
{
BFMatsSQL.Insert();
}
}
protected void BFMatsSQL_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
DropDownList ddlNewMfr =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewMfr");
DropDownList ddlNewThickness =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewThickness");
DropDownList ddlNewCore =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewCore");
DropDownList ddlNewSize =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewSize");
TextBox txtNewColor =
(TextBox)gvBFMats.FooterRow.FindControl("txtNewColor");
TextBox txtNewQty =
(TextBox)gvBFMats.FooterRow.FindControl("txtNewQty");
DropDownList ddlNewFinish =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewFinish");
TextBox txtNewExtra =
(TextBox)gvBFMats.FooterRow.FindControl("txtNewExtra");
// Set the SQLDataSource's InsertParameters values
e.InputParameters["MatManufacturerID"] =
Convert.ToInt32(ddlNewMfr.SelectedValue);
e.InputParameters["MatThicknessID"] =
Convert.ToInt32(ddlNewThickness.SelectedValue);
e.InputParameters["MatCoreID"] =
Convert.ToInt32(ddlNewCore.SelectedValue);
e.InputParameters["MatSizeID"] =
Convert.ToInt32(ddlNewSize.SelectedValue);
e.InputParameters["MatFinishPrePostID"] =
Convert.ToInt32(ddlNewFinish.SelectedValue);
string strNewColor = null;
if (!string.IsNullOrEmpty(txtNewColor.Text))
strNewColor = txtNewColor.Text;
e.InputParameters["MatFinishColor"] = strNewColor;
int? intNewQty = null;
if (!string.IsNullOrEmpty(txtNewQty.Text))
intNewQty = Convert.ToInt32(txtNewQty.Text);
e.InputParameters["MatQty"] = intNewQty;
string strNewExtra = null;
if (!string.IsNullOrEmpty(txtNewExtra.Text))
strNewExtra = txtNewExtra.Text;
e.InputParameters["MatNumExtraSheets"] = strNewExtra;
}
具体来说,我在 (Control)gvBFMats.FooterRow.FindControl("Control ID");
中的 gvBFMats 下看到了红色的波浪线,上面写着 "The name 'gvBFMats' does not exist in the current context." 我只是猜测它不喜欢在嵌套在一个窗体视图模板。有没有办法以编程方式传递此上下文?
你说得对,它无法识别名称 gvBFMats
,因为它嵌入在模板中。只有 "top-level",非嵌入式控件将在代码隐藏中被视为已明确声明。在模板中声明的控件不会。编译器无法识别这些名称。
这是有原因的。假设您在 ItemTemplates
之一中有一个名为 TextBox1
的控件,用于重复控件。你绑定它。您页面的控件树现在有许多 ID 为 TextBox1
的控件。如果你想引用 TextBox1
,它怎么知道你指的是哪一个?
所以。在你的情况下你能做什么?好吧,BFMatsSQL_Inserting
和 gvBFMats_RowCommand
都是事件处理程序,因此您不能更改它们的签名。
但是,您可以使用属于同一个 class 的它们,并使用模块级变量来保存对 gvBFMats
的引用。像这样:
private GridView gvBFMats;
protected void gvBFMats_RowCommand(object sender, GridViewCommandEventArgs e)
{
gvBFMats = [your form view].Row.FindControl("gvBFMats") as GridView;
if (e.CommandName == "Insert" && Page.IsValid)
{
BFMatsSQL.Insert();
}
}
现在,BFMatsSQL_Inserting
可以引用 gvBFMats
,它应该有一个值。