如何通过用户控件公开ITemplate?

时间:2009-09-14 15:00:01

标签: c# asp.net

为了更轻松地创建表单,我们使用了用户控件中的修改后的Formview控件。此用户控件用于网格和FormView,您可以选择网格中的项目,FormView以模式显示以供查看/编辑:

<I2CL:Grid runat="server" ID="Grid" OnSelecting="Selecting" ShowCreate="true" />
<I2:Modal ID="SFModal" runat="server" UpdateMode="Conditional">
 <ContentTemplate>
     <I2:FormView runat="server" ID="FVSubForm" DefaultMode="Edit" DataSourceID="DSSubForm" />
     <I2:ILDataSource ID="DSSubForm" runat="server" />
 </ContentTemplate>
</I2:Modal>

在页面中,控件如下所示:

<I2C:TabGrid ID="TG" runat="server" Property="ParentProperty">
  <Columns>
    <I2:Column Header="Column 1" DataSource="Column1" />
    <I2:Column Header="Column 2" DataSource="Column2" />
  </Columns>
  <EditItemTemplate>
    <I2Form:Dropdown ID="Col1" runat="server" SelectedValue='<%# Bind("Column1") %>' List="Column1Options" />
    <I2Form:Textbox ID="Col2" runat="server" Text='<%# Bind("Column2") %>' />
  </EditItemTemplate>
</I2C:TabGrid>

问题是我们使用的EditItemTemplate。我可以弄清楚如何连接它的唯一方法是在TabGrid控件中有一个ITemplate并在OnInit中应用引用:

[PersistenceMode(PersistenceMode.InnerProperty), 
 TemplateContainer(typeof(FormView))]
public ITemplate EditItemTemplate { get; set; }

protected override void OnInit(EventArgs e)
{
 base.OnInit(e);
 FVSubForm.EditItemTemplate = EditItemTemplate;
}

这个问题是因为引用是用户控件中的对象,所以与FormView中的字典条目绑定的EditItemTemplate引用会被破坏,所以当你获得发送给数据源的更改字典时,他们在每次回发时都是空的。

此处使用的I2:ILDataSource是最接近ObjectDataSource的自定义实现。它不是通用对象调用,而是直接调用页面中的GetEntity()(或本例中的用户控件)和UpdateEntity(obj Entity)来保存。由于这是一个非常具体的场景,我们可以消除ObjectDataSource中90%的代码。

我希望能够将<EditItemTemplate>中的<I2C:TabGrid>直接指向<EditItemTemplate>内的<I2:FormView>这是可能的,还是有人有其他途径的建议?

注意:我尝试将FVSubForm上的EditItemTemplate公开为代理属性,但这不起作用,因为在创建子控件之前在用户控件上设置了属性,因此FVSubForm为null。如果这可以解决,我当然都是耳朵。

1 个答案:

答案 0 :(得分:5)

您需要做的一件事是将您的ITemplate属性标记为支持双向数据绑定:

[TemplateContainer(typeof(FormView), System.ComponentModel.BindingDirection.TwoWay )]

如果没有这个,ASP.NET将不会为允许Bind()表达式工作的页面生成正确的代码。

我不确定这是否是您所需要的,但这是值得尝试的。

大卫