2

我有一个 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

http://forums.asp.net/p/1379371/2911424.aspx#2911424?Data+Binding+with+Dynamically+Created+controls+not+working+both+ways

简而言之,在 Page.OnInit 方法中,我将模板的一个实例分配给 FormView EditItemTemplate、EmptyDataTemplate、InsertItemTemplate 和 ItemTemplate 属性(每个属性的不同实例,具有该模板的适当控件、布局等)。我看到调用了与默认模式对应的模板的 InstantiateIn 方法,正确创建了控件层次结构,并且按预期呈现了 UI。

我的每个模板中都有一组启用模式切换的按钮控件。因此,例如,在 ItemTemplate 中,我有一个带有 CommandName="New" 的按钮。我希望单击此按钮将导致 FormView 更改为插入模式。相反,我得到回发并在我的 ItemTemplate 上调用 InstantiateIn。我附加到 FormView 的 ModeChanging 和 ModeChanged 事件的处理程序不会触发。

当我逐步浏览控制层次结构时,我看到的对象模型与我在标记中创建的页面相同——但有一个例外。我使用 HtmlTable、HtmlTableRow 和 HtmlTableCell 控件来构建布局,而标记使用 <table>、<tr> 和 <td> 元素。

对我所缺少的有什么想法吗?我真的很想通过自动绑定(通过事件冒泡)来改变模式,而不是手动创建和编码按钮及其操作。

以下是用于生成模板的代码:

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);
    }
}

(请注意,模板已缓存,因此控制层次结构仅构建一次。)

4

0 回答 0