0

より良いカスタム コントロールのために ITemplate を使用する方法を学ぼうとしています。ほとんど機能していますが、ページからコンテナのプロパティにアクセスする方法を理解できませんでした。

ここに私のテンプレート化されたコントロールがあります:

[ParseChildren(true)]
[PersistChildren(false)]
public partial class Example : UserControl
{
    private ITemplate _CustomPanelContainer;

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [TemplateContainer(typeof(CustomPanelContainer))]
    [TemplateInstance(TemplateInstance.Single)]
    public virtual ITemplate CustomPanel
    {
        get { return _CustomPanelContainer; }
        set { _CustomPanelContainer = value; }
        
    }


    protected override void CreateChildControls()
    {
        Controls.Clear();
        if (_CustomPanelContainer != null)
        {
            var p = new Panel();
            p.ID = "CustomPanel";
            Controls.Add(p);
            _CustomPanelContainer.InstantiateIn(p);
        }
        base.CreateChildControls();
    }


    public class CustomPanelContainer : Panel, INamingContainer 
    {
        
        private string _Test = "TESTING!";
        public string TextTest 
        { 
            get 
            { 
                return _Test;
            }
            set
            {
                _Test = value;
            }
        }
    }
}

ページの実装は次のとおりです。

<uc1:Example runat="server" ID="Example1">
        <CustomPanel>
            <strong>Test: </strong> <%# Container.TextTest %>
        </CustomPanel>
    </uc1:Example>

ほとんど動作していますが、問題は <%# Container.TextTest %> が常に空の文字列を返すことです。デバッガーで実行すると、CustomPanelContainer の TextTest プロパティ内の行にブレークポイントを設定しましたが、ブレークポイントにヒットしないため、実際にプロパティにアクセスすることはありません。

ここで何が欠けていますか?<%#Container 経由でコンテナーのパブリック プロパティへのアクセスを有効にするにはどうすればよいですか?

4

1 に答える 1

0

私は最終的に、それを自分の望むように動作させる方法を見つけました。

Container のタイプとして ITemplate を削除し、タイプを実際のタイプとして設定し、DataBind() コマンドを CreateChildControls() に追加しました。

これを行う正しい方法ではないかもしれませんが、うまくいきます。

私はまだここで何をしているのか本当にわからないので、誰かが批評やより良いアプローチを提供しているかどうかを確認するために、質問を開いたままにしておきます。

簡略化された作業コード:

[ParseChildren(true)]
[PersistChildren(false)]
public partial class Example : UserControl
{

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [TemplateInstance(TemplateInstance.Single)]
    public virtual CustomPanelContainer Template { get; set; }


    protected override void CreateChildControls()
    {
        Controls.Clear();
        if (Template != null)
        {
            Template.DataBind();
            Controls.Add(Template);
        }
        base.CreateChildControls();
    }

    

    public class CustomPanelContainer : Panel, INamingContainer
    {
        public string TextTest
        {
            get { return "TESTING!"; }
        }
    }
}

ページの実装:

<uc1:Example runat="server" ID="Example">
    <Template>
        <strong>Test: </strong><span><%# Container.TextTest %></span>
    </Template>
</uc1:Example>

編集:これは、テンプレートのタイプを非表示にする必要がある場合にも機能します。つまり、上記のコードは Template のタイプを公開して、Panel のプロパティを Template の属性として操作できるようにしますが、以下のコードは Template のタイプを非表示にして、そのプロパティの操作をブロックします。

[ParseChildren(true)]
[PersistChildren(false)]
public partial class Example : UserControl
{

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [TemplateInstance(TemplateInstance.Single)]
    [TemplateContainer(typeof(CustomPanelContainer))]
    public virtual ITemplate Template { get; set; }


    protected override void CreateChildControls()
    {
        Controls.Clear();
        if (Template != null)
        {
            var p = new CustomPanelContainer();
            Template.InstantiateIn(p);
            p.DataBind();
            Controls.Add(p);
        }
        base.CreateChildControls();
    }

    

    public class CustomPanelContainer : Panel, INamingContainer
    {
        public string TextTest
        {
            get { return "TESTING!"; }
        }
    }
于 2021-10-22T17:46:28.473 に答える