无法使用动态 FormView 模板更改模式
我有一个 ASP.NET 页面,其中 FormView 数据绑定到 ObjectDataSource,该页面使用动态生成的模板根据应用程序数据库中的布局信息呈现 UI。我已经能够正确渲染模板,并且一切看起来都很好,直到我单击其中一个按钮来更改模式 - 没有任何变化。
我的代码基于以下文章/帖子中提供的解释:
http://www. codeproject.com/KB/aspnet/DynamicFormview.aspx
http:// msdn.microsoft.com/en-us/library/ms227423.aspx
http://msdn.microsoft.com/en-us/library/y0h809ak(vs.71).aspx
简而言之,在 Page.OnInit 方法中,我将模板的实例分配给 FormView EditItemTemplate, EmptyDataTemplate、InsertItemTemplate 和 ItemTemplate 属性(每个属性的不同实例,以及该模板的相应控件、布局等)。我看到对应于默认模式的模板的 InstantiateIn 方法被调用,控件层次结构已正确创建,并且 UI 按预期呈现。
我的每个模板中都有一组按钮控件,可以启用模式切换。例如,在 ItemTemplate 中,我有一个 CommandName=“New”的按钮。我预计单击此按钮将导致 FormView 更改为插入模式。相反,我收到回发,并在我的 ItemTemplate 上调用 InstantiateIn。我附加到 FormView 的 ModeChanging 和 ModeChanged 事件的处理程序不会触发。
当我单步浏览控件层次结构时,我看到与我在标记中创建的页面相同的对象模型 - 但有一个例外。我使用 HtmlTable、HtmlTableRow 和 HtmlTableCell 控件来构造布局,而标记使用 、 和
元素。 |
对我所缺少的有什么想法吗?我真的很想通过自动绑定(通过事件冒泡)来更改模式,而不必手动创建和编码按钮及其操作。
以下是用于生成模板的代码:(
public class FormViewTemplate : INamingContainer, ITemplate
{
private Boolean _childControlsCreated;
private Panel _panel;
public FormViewTemplate(TemplateMode mode) { Mode = mode; }
public TemplateMode Mode { get; private set; }
private void CreateChildControls()
{
_panel = new Panel();
_panel.Controls.Add(CreateButtons());
switch (Mode)
{
case TemplateMode.Edit:
_panel.Controls.Add(new LiteralControl("Edit Mode"));
break;
case TemplateMode.Empty:
_panel.Controls.Add(new LiteralControl("Empty Mode"));
break;
case TemplateMode.Insert:
_panel.Controls.Add(new LiteralControl("Insert Mode"));
break;
case TemplateMode.ReadOnly:
_panel.Controls.Add(new LiteralControl("Read-Only Mode"));
break;
}
}
private Panel CreateButtons()
{
var panel = new Panel();
var table = new HtmlTable()
{
Border = 0,
CellPadding = 2,
CellSpacing = 0
};
panel.Controls.Add(table);
var tr = new HtmlTableRow();
table.Rows.Add(tr);
var td = new HtmlTableCell();
tr.Cells.Add(td);
var addButton = new ASPxButton()
{
CommandName = "New",
Enabled = (Mode == TemplateMode.ReadOnly),
ID = "AddButton",
Text = "Add"
};
td.Controls.Add(addButton);
return panel;
}
private void EnsureChildControls()
{
if (!_childControlsCreated)
{
CreateChildControls();
_childControlsCreated = true;
}
}
void ITemplate.InstantiateIn(Control container)
{
EnsureChildControls();
container.Controls.Add(_panel);
}
}
请注意,模板被缓存,因此控件层次结构仅构建一次。)
I have an ASP.NET page with a FormView data-bound to an ObjectDataSource that uses dynamically generated templates to render the UI based on layout information from the application's database. I've been able to get the templates to render correctly and everything seems fine until I click one of the buttons to change modes - nothing changes.
My code is based on the explanations provided in the following articles/posts:
http://www.codeproject.com/KB/aspnet/DynamicFormview.aspx
http://msdn.microsoft.com/en-us/library/ms227423.aspx
http://msdn.microsoft.com/en-us/library/y0h809ak(vs.71).aspx
In a nutshell, in the Page.OnInit method I assign an instance of my templates to the FormView EditItemTemplate, EmptyDataTemplate, InsertItemTemplate and ItemTemplate properties (a different instance for each property with the appropriate controls, layout, etc for that template). I see that the InstantiateIn method of the template corresponding to the default mode is called, the control hierarchy is created correctly and the UI rendered as expected.
I have a set of button controls in each of my templates that enable the mode switches. So, for instance, in the ItemTemplate, I have a button with CommandName="New". I expect that clicking this button will cause the FormView to change into the Insert mode. Instead, I get the postback and InstantiateIn is called on my ItemTemplate. The handlers I've attached to the FormView's ModeChanging and ModeChanged events do not fire.
When I step through the control hierarchy, I see the same object model as the page I created in markup - with one exception. I am using the HtmlTable, HtmlTableRow and HtmlTableCell controls to construct the layout whereas the markup uses <table>, <tr> and <td> elements.
Any thoughts on what I'm missing? I'd really like to get this working with the automatic binding (through event bubbling) to change modes rather than have to manually create and code the buttons and their actions.
Here is the code used to generate the template:
public class FormViewTemplate : INamingContainer, ITemplate
{
private Boolean _childControlsCreated;
private Panel _panel;
public FormViewTemplate(TemplateMode mode) { Mode = mode; }
public TemplateMode Mode { get; private set; }
private void CreateChildControls()
{
_panel = new Panel();
_panel.Controls.Add(CreateButtons());
switch (Mode)
{
case TemplateMode.Edit:
_panel.Controls.Add(new LiteralControl("Edit Mode"));
break;
case TemplateMode.Empty:
_panel.Controls.Add(new LiteralControl("Empty Mode"));
break;
case TemplateMode.Insert:
_panel.Controls.Add(new LiteralControl("Insert Mode"));
break;
case TemplateMode.ReadOnly:
_panel.Controls.Add(new LiteralControl("Read-Only Mode"));
break;
}
}
private Panel CreateButtons()
{
var panel = new Panel();
var table = new HtmlTable()
{
Border = 0,
CellPadding = 2,
CellSpacing = 0
};
panel.Controls.Add(table);
var tr = new HtmlTableRow();
table.Rows.Add(tr);
var td = new HtmlTableCell();
tr.Cells.Add(td);
var addButton = new ASPxButton()
{
CommandName = "New",
Enabled = (Mode == TemplateMode.ReadOnly),
ID = "AddButton",
Text = "Add"
};
td.Controls.Add(addButton);
return panel;
}
private void EnsureChildControls()
{
if (!_childControlsCreated)
{
CreateChildControls();
_childControlsCreated = true;
}
}
void ITemplate.InstantiateIn(Control container)
{
EnsureChildControls();
container.Controls.Add(_panel);
}
}
(Note that the template is cached so the control hierarchy is only built once.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论