1

ここに私が欲しいものがあります:

コントロールをページに配置して、他の開発者がフォーム要素を内部に配置して、コントロールが検索しているエンティティを表示できるようにしたいと考えています。検索ロジックがすべて機能しています。コントロールは、カスタム検索フィールドを作成し、インターフェイスを実装する宣言型 C# クラスに基づいて検索を実行しSearchSpecます。

これが私が試してきたことです:

INamingContainer を実装する WebControl で ITemplate を使用してみました CompositeControl を実装してみました

作業に最も近いのは以下です。

OK、カスタム WebControl があります

[
AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal),
DefaultProperty("SearchSpecName"),
ParseChildren(true),
ToolboxData("<{0}:SearchPage runat=\"server\"> </{0}:SearchPage>")
]
public class SearchPage : WebControl, INamingContainer
{

    [Browsable(false),
    PersistenceMode(PersistenceMode.InnerProperty),
    DefaultValue(typeof(ITemplate), ""),
    Description("Form template"),
    TemplateInstance(TemplateInstance.Single),
    TemplateContainer(typeof(FormContainer))]
    public ITemplate FormTemplate { get; set; }

    public class FormContainer : Control, INamingContainer{ }

    public Control MyTemplateContainer { get; private set; }

    [Bindable(true), Category("Behavior"), DefaultValue(""),
     Description("The class name of the SearchSpec to use."), Localizable(false)]
    public virtual string SearchSpecName
    {
        get;
        set;
    }

    [Bindable(true), Category("Behavior"), DefaultValue(true), 
    Description("True if this is query mode."), Localizable(false)]
    public virtual bool QueryMode
    {
        get;
        set;
    }

    private SearchSpec _spec;
    private SearchSpec Spec
    {
        get
        {
            if (_spec == null)
            {
                Type type = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.Name == SearchSpecName).First();
                _spec = (SearchSpec)Assembly.GetExecutingAssembly().CreateInstance(type.Namespace + "." + type.Name);
            }
            return _spec;
        }
    }

    protected override void CreateChildControls()
    {
        if (FormTemplate != null)
        {
            MyTemplateContainer = new FormTemplateContainer(this);
            FormTemplate.InstantiateIn(MyTemplateContainer);
            Controls.Add(MyTemplateContainer);
        }
        else
        {
            Controls.Add(new LiteralControl("blah"));
        }

    }

    protected override void RenderContents(HtmlTextWriter writer)
    {
        // <snip>
    }


    protected override HtmlTextWriterTag TagKey
    {
        get
        {
            return HtmlTextWriterTag.Div;
        }
    }

}

public class FormTemplateContainer : Control, INamingContainer
{
    private SearchPage parent;
    public FormTemplateContainer(SearchPage parent)
    {
        this.parent = parent;
    }
}

次に使用法:

<tster:SearchPage ID="sp1" runat="server" SearchSpecName="TestSearchSpec" QueryMode="False">
 <FormTemplate>
    <br />
    Test Name:
    <asp:TextBox ID="testNameBox" runat="server" Width="432px"></asp:TextBox>
    <br />
    Owner:
    <asp:TextBox ID="ownerBox" runat="server" Width="427px"></asp:TextBox>
    <br />
    Description:
    <asp:TextBox ID="descriptionBox" runat="server" Height="123px" Width="432px" 
        TextMode="MultiLine" Wrap="true"></asp:TextBox>
 </FormTemplate>
</tster:SearchPage>

問題は、CodeBehind で、ページにメンバー descriptionBox、ownerBox、および testNameBox があることです。ただし、それらはすべてヌルです。さらに、 と同様FindControl("ownerBox")に null を返しますthis.sp1.FindControl("ownerBox")。私はthis.sp1.MyTemplateContainer.FindControl("ownerBox")コントロールを得るためにしなければなりません。

開発者がこれを実行できるように、C#コードビハインドでコントロールが生成され、Page_Loadイベントでnullにならないようにするにはどうすればよいですか:

testNameBox.Text = "foo";
ownerBox.Text = "bar";
descriptionBox.Text = "baz";
4

1 に答える 1

0

OK、SearchPage を Panel 拡張にして ParseChildren(true) を削除することでこれを修正しました。

于 2010-04-18T16:13:34.670 に答える