9

次の構造を持つカスタム WebControl を作成しました。

<gws:ModalBox ID="ModalBox1" HeaderText="Title" runat="server">
    <Contents>
        <asp:Label ID="KeywordLabel" AssociatedControlID="KeywordTextBox" runat="server">Keyword: </asp:Label><br />
        <asp:TextBox ID="KeywordTextBox" Text="" runat="server" />
    </Contents>
    <Footer>(controls...)</Footer>
</gws:ModalBox>

コントロールには、'Contents' と 'Footer' の 2 つの ControlCollection プロパティが含まれています。複数のコントロール コレクションでコントロールを構築しようとしたことはありませんが、次のように解決しました (簡略化):

[PersistChildren(false), ParseChildren(true)]
public class ModalBox : WebControl
{
    private ControlCollection _contents;
    private ControlCollection _footer;

    public ModalBox()
        : base()
    {
        this._contents = base.CreateControlCollection();
        this._footer = base.CreateControlCollection();
    }

    [PersistenceMode(PersistenceMode.InnerProperty)]
    public ControlCollection Contents { get { return this._contents; } }

    [PersistenceMode(PersistenceMode.InnerProperty)]
    public ControlCollection Footer { get { return this._footer; } }

    protected override void RenderContents(HtmlTextWriter output)
    {
        // Render content controls.
        foreach (Control control in this.Contents)
        {
            control.RenderControl(output);
        }

        // Render footer controls.
        foreach (Control control in this.Footer)
        {
            control.RenderControl(output);
        }
    }
}

ただし、適切にレンダリングされているようですが、プロパティ内にasp.netラベルと入力コントロールを追加すると機能しなくなります(上記のasp.netコードを参照)。私はHttpExceptionを取得します:

ラベル 'KeywordLabel' に関連付けられている ID 'KeywordTextBox' のコントロールが見つかりません。

コントロールコレクションのテキストボックスの前にラベルが表示されるため、ある程度理解できます。ただし、デフォルトのasp.netコントロールでは機能しますが、なぜこれが機能しないのですか? 私は何を間違っていますか?1 つのコントロールに 2 つのコントロール コレクションを含めることさえ可能ですか? 別の方法でレンダリングする必要がありますか?

返信ありがとうございます。

4

2 に答える 2

2

2 つのコントロール コレクションの親として 2 つの Panel を使用できます (グループ化と読みやすさが提供されます)。各コレクションのコントロールをそれぞれのパネルの Controls コレクションに追加し、Render メソッドで各パネルの Render メソッドを呼び出すだけです。パネルは自動的に子をレンダリングし、独自の名前空間を提供するため、異なるパネルで同様の ID を持つコントロールを使用できます。

于 2010-03-25T08:53:43.237 に答える
1

それがうまくいくかどうかはわかりません。ただし、テンプレートを使用すると、出力を正しくレンダリングするコントロールを取得できます。

まず、コンテナ コントロールの型として使用するクラスを定義します。

public class ContentsTemplate : Control, INamingContainer
{
}

そして今、カスタム コントロール:

[PersistChildren(false), ParseChildren(true)]
public class ModalBox : CompositeControl
{

  [PersistenceMode(PersistenceMode.InnerProperty)]
  [TemplateContainer(typeof(ContentsTemplate))]
  public ITemplate Contents { get; set; }

  [PersistenceMode(PersistenceMode.InnerProperty)]
  [TemplateContainer(typeof(ContentsTemplate))]
  public ITemplate Footer { get; set; }

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

    var contentsItem = new ContentsTemplate();
    Contents.InstantiateIn(contentsItem);
    Controls.Add(contentsItem);

    var footerItem = new ContentsTemplate();
    Footer.InstantiateIn(footerItem);
    Controls.Add(footerItem);
  }

}
于 2010-03-19T05:25:31.773 に答える