簡體   English   中英

無法將類型'System.Web.UI.CompiledTemplateBuilder'隱式轉換為自定義ITemplate

[英]Cannot implicitly convert type 'System.Web.UI.CompiledTemplateBuilder' to custom ITemplate

創建ListView時,控件上有一個屬性,可讓您在LayoutTemplate中指定用於保存每個項目的控件的PlaceHolder的ID。

<asp:ListView ID="lvTest" runat="server" ItemPlaceholderID="testPlaceholder">
    <LayoutTemplate>
        <ul>
            <asp:PlaceHolder ID="testPlaceholder" runat="server" />
        </ul>
    </LayoutTemplate>
    <ItemTemplate>
        <li>Item</li>
    </ItemTemplate>
</asp:ListView>

我正在嘗試創建自定義模板服務器控件,但由於我希望有幾個不同的模板,因此希望模板本身具有屬性。 我極為簡化的瑣碎示例如下:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ControlLibrary
{
    [ParseChildren(true)]
    public class TestContainer : Control, INamingContainer
    {
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [TemplateContainer(typeof(TestContainer))]
        public TestTemplate TestTemplate { get; set; }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            DataBind();
        }

        public override void DataBind()
        {
            base.DataBind();

            CreateChildControls();
        }

        protected override void CreateChildControls()
        {
            Controls.Clear();

            var phTest = new PlaceHolder();
            phTest.ID = "phTest";

            Controls.Add(phTest);

            if (this.TestTemplate != null)
                this.TestTemplate.InstantiateIn(phTest);

            this.ChildControlsCreated = true;
        }
    }

    public class TestTemplate : ITemplate
    {
        public string Name { get; set; }

        public void InstantiateIn(Control container)
        {
            container.Controls.Add(new LiteralControl(this.Name));
        }
    }
}

但是,如果將模板添加到如下所示的.aspx文件中,則會收到錯誤消息CS0029:無法將類型'System.Web.UI.CompiledTemplateBuilder'隱式轉換為'ControlLibrary.TestTemplate'

<CustomControls:TestContainer ID="testContainer" runat="server">
    <TestTemplate>
        test
    </TestTemplate>
</CustomControls:TestContainer>

是否可以這樣做,還是我必須將所有可配置屬性放在父容器本身上?

感謝您的任何幫助,您可以提供!

您正確地完成了所有工作,除了模板屬性聲明。 任何模板都必須聲明為System.Web.UI.ITemplate 只需將模板聲明替換為:

public ITemplate TestTemplate { get; set; }

它應該開始工作。 有關參考,請參見如何:創建模板化ASP.NET用戶控件

要使用模板的自定義屬性來完成一項技巧,您需要再添加一個繼承自collection的類:

public class TestTemplateList : List<TestTemplate> { }

並如下更改控件的聲明:

[ParseChildren(true, DefaultProperty = "TestTemplates")]
public class TestContainer : Control, INamingContainer
{
    [PersistenceMode(PersistenceMode.InnerProperty)]
    public TestTemplateList TestTemplates { get; set; }

    // ... OnLoad and DataBind left intact

    protected override void CreateChildControls()
    {
        Controls.Clear();

        var phTest = new PlaceHolder();
        phTest.ID = "phTest";

        Controls.Add(phTest);

        if (this.TestTemplates != null)
        {
            foreach (var testTemplate in TestTemplates)
            {
                ((ITemplate)testTemplate).InstantiateIn(phTest);    
            }
        }

        this.ChildControlsCreated = true;
    }
}

之后,您應該能夠以兩種方式聲明控制權。 您可以跳過指定TestTemplates因為它在ParseChildrenAttribute被聲明為DefaulProperty

<CustomControls:TestContainer runat="server" ID="testContainer">
    <CustomControls:TestTemplate Name="test">
    </CustomControls:TestTemplate>
</CustomControls:TestContainer>

<%-- OR --%>

<CustomControls:TestContainer runat="server" ID="wc11">
    <TestTemplates>
        <CustomControls:TestTemplate Name="test">
        </CustomControls:TestTemplate>
    </TestTemplates>
</CustomControls:TestContainer>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM