使用ITemplate在自定义控件上进行数据绑定

6
这是我的自定义服务器控件的示例代码:
[Designer(typeof(ContainerControlDesigner))]
[ToolboxData("<{0}:BlocArrondi runat=server><ContenuPrincipal></ContenuPrincipal></{0}:BlocArrondi>")]
public class BlocArrondi : WebControl
{
    private ITemplate _ContenuPrincipal;
    protected Panel _PanelContenuPrincipal = new Panel();

    public BlocArrondi()
    : base(HtmlTextWriterTag.Div)
    {

    }

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [TemplateInstance(TemplateInstance.Single)]
    public ITemplate ContenuPrincipal
    {
            get { return _ContenuPrincipal; }
            set { _ContenuPrincipal = value; }
    }

    protected override void OnInit(EventArgs e)
    {
            base.OnInit(e);
            _PanelContenuPrincipal.ID = "PanelPrincipal";
            this.Controls.Add(_PanelContenuPrincipal);

            if (_ContenuPrincipal != null)
                    _ContenuPrincipal.InstantiateIn(_PanelContenuPrincipal);
    }
}

以下是实现代码:

<controls:BlocArrondi runat="server">
    <ContenuPrincipal>
        <asp:Label id="LabelInfo" runat="server" />
    </ContenuPrincipal>
</controls:BlocArrondi>

我的标签LabelInfo在代码后台是可访问的,太好了!

但是如果我在Repeater或ListView中使用自定义控件,在ContenuPrincipal模板内就不能使用Container.DataItem属性:

<asp:Repeater id="RepeaterInfos" runat="server">
    <ItemTemplate>
        <controls:BlocArrondi runat="server">
            <ContenuPrincipal>
                <asp:Label runat="server" Text="<%# (Container.DataItem as MsgInfo).DisplayMessage() " />
            </ContenuPrincipal>
        </controls:BlocArrondi>
    </ItemTemplate>
</asp:Repeater>

错误信息:

'System.Web.UI.Control'不包含名为'DataItem'的定义,也没有接受类型为'System.Web.UI.Control'的第一个参数的扩展方法'DataItem'可以找到(您是否缺少使用指令或程序集引用?)

如何在我的控件的ContenuPrincipal模板中使用Container.DataItem属性?
1个回答

4

我通过继承IDataItemContainer自定义了一个TemplateContainer来解决我的问题:

    public class BlocArrondiContainer : Panel, IDataItemContainer

更改:

    protected Panel _PanelContenuPrincipal = new Panel();

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [TemplateInstance(TemplateInstance.Single)]
    public ITemplate ContenuPrincipal
    {
        get { return _ContenuPrincipal; }
        set { _ContenuPrincipal = value; }
    }

由:

    protected BlocArrondiContainer _PanelContenuPrincipal = new BlocArrondiContainer ();

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [TemplateInstance(TemplateInstance.Single)]
    [TemplateContainer(typeof(BlocArrondiContainer))]
    public ITemplate ContenuPrincipal
    {
        get { return _ContenuPrincipal; }
        set { _ContenuPrincipal = value; }
    }

在BlocArrondi类中覆盖OnDataBinding方法:
    protected override void OnDataBinding(System.EventArgs e)
    {
        if (NamingContainer is IDataItemContainer)
            _PanelContenuPrincipal.DataItem = (NamingContainer as IDataItemContainer).DataItem;

        base.OnDataBinding(e);
    }

很棒的解决方案,我也差不多想到了这个。 - Johan Buret

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接