1

ASP.Net の「PasswordRecovery」コントロールと同様の方法で機能する、テンプレート化された複合コントロールを作成しようとしています。

つまり、ユーザーは独自のテンプレートを定義できますが、定義済みのコントロール ID を使用することで、どのフィールドが電子メール アドレスで、どのボタンが電子メールを送信するかを定義します。

テンプレート化された Web サーバー コントロールのドキュメントを調べてみましたが、それらのコントロールに動作を追加することについて話しているものは見つかりません。

または、PasswordRecovery の動作を完全に変更する方法はありますか? そのコントロールの一般的な動作ではなく、パスワードを変更するためのワンタイム URL を記載した電子メールを送信したいと考えています。

4

2 に答える 2

4

私は関連する質問に答えました:

https://stackoverflow.com/a/11700540/1268570

しかし、この答えでは、私はさらに深く行きます。

設計サポートとカスタム動作を備えたテンプレート化されたサーバーコントロールを投稿します。

コンテナコード

[ToolboxItem(false)]
public class TemplatedServerAddressContainer : WebControl, INamingContainer
{
    public string Address { get; protected set; }

    public TemplatedServerAddressContainer(string address)
    {
        this.Address = address;
    }
}
  • 上記のコントロールは、コントロールに送信するデータをOUTPUTとして保持する役割を果たします。これが、テンプレートをインスタンス化するコントロールになります

サーバー制御

[DefaultProperty("Address")]
[ToolboxItem(true)]
[ToolboxData("<{0}:TemplatedServerAddressControl runate=server></{0}:TemplatedServerAddressControl>")]
[Designer(typeof(TemplatedServerAddressDesigner))]
//[ToolboxBitmap(typeof(TemplatedServerAddressControl), "")]
[Description("My templated server control")]
[ParseChildren(true)]
public class TemplatedServerAddressControl : WebControl
{
    private TemplatedServerAddressContainer addressContainer;

    [Bindable(true)]
    [Localizable(true)]
    [DefaultValue(null)]
    [Description("The custom address")]
    [Category("Apperance")]
    [Browsable(true)]
    public string Address
    {
        get
        {
            return (this.ViewState["Address"] ?? string.Empty).ToString();
        }
        set
        {
            this.ViewState["Address"] = value;
        }
    }

    [Browsable(false)]
    [DefaultValue(null)]
    [Description("Address template")]
    [PersistenceMode(PersistenceMode.InnerProperty)]
    [TemplateContainer(typeof(TemplatedServerAddressContainer))]
    [TemplateInstance(TemplateInstance.Multiple)]
    public ITemplate AddressTemplate { get; set; }

    [Browsable(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public TemplatedServerAddressContainer AddressContainer
    {
        get
        {
            this.EnsureChildControls();

            return this.addressContainer;
        }
        internal set
        {
            this.addressContainer = value;
        }
    }

    public override ControlCollection Controls
    {
        get
        {
            this.EnsureChildControls();

            return base.Controls;
        }
    }

    public override void DataBind()
    {
        this.CreateChildControls();
        this.ChildControlsCreated = true;

        base.DataBind();
    }

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

        if (this.AddressTemplate != null)
        {
            this.addressContainer = new TemplatedServerAddressContainer(this.Address);

            this.AddressTemplate.InstantiateIn(this.addressContainer);
            this.Controls.Add(this.addressContainer);
        }
    }

    protected override bool OnBubbleEvent(object source, EventArgs args)
    {
        if (args is CommandEventArgs)
        {
            var commandArgs = args as CommandEventArgs;

            switch (commandArgs.CommandName)
            {
                case "DoSomething":
                    // place here your custom logic
                    this.Page.Response.Write("Command bubbled");
                    return true;
            }
        }

        return base.OnBubbleEvent(source, args);
    }
}
  • public string AddressプロパティはコントロールINPUTとして使用され、タスクを実行するために必要なすべての入力プロパティを作成できます。

  • public ITemplate AddressTemplate { get; set; }これは、コントロールのテンプレートを表します。このプロパティに付ける名前は、テンプレートの名前としてページのマークアップで使用される名前になります

  • public TemplatedServerAddressContainer AddressContainerこのプロパティは、デザイナーのサポートのみを目的としています

  • 子コントロールを正しく作成するには、次のメソッドとプロパティをオーバーライドする必要があります。ControlsDataBindおよびCreateChildControls

  • をオーバーライドするOnBubbleEventと、コントロールからの特定のイベントに反応できるようになります。

デザイナーのサポート

public class TemplatedServerAddressDesigner : ControlDesigner
{
    private TemplatedServerAddressControl controlInstance;

    public override void Initialize(IComponent component)
    {
        this.controlInstance = (TemplatedServerAddressControl)component;

        base.Initialize(component);
    }

    public override string GetDesignTimeHtml()
    {
        var sw = new StringWriter();
        var htmlWriter = new HtmlTextWriter(sw);
        var controlTemplate = this.controlInstance.AddressTemplate;

        if (controlTemplate != null)
        {
            this.controlInstance.AddressContainer = new TemplatedServerAddressContainer(
                this.controlInstance.Address
                );
            controlTemplate.InstantiateIn(this.controlInstance.AddressContainer);

            this.controlInstance.DataBind();

            this.controlInstance.RenderControl(htmlWriter);
        }

        return sw.ToString();
    }
}

ASPXマークアップ

<%@ Register Assembly="Msts" Namespace="Msts.Topics.Chapter07___Server_Controls.Lesson02___Server_Controls" TagPrefix="address" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <address:TemplatedServerAddressControl runat="server" ID="addressControl1">
        <AddressTemplate>
            <b>
                Address:
            </b>
            <u>
                <asp:Literal Text="<%# Container.Address %>" runat="server" />
            </u>
            <asp:Button Text="text" runat="server" OnClick="Unnamed_Click" ID="myButton" />
            <br />
            <asp:Button Text="Command bubbled" runat="server" CommandName="DoSomething" OnClick="Unnamed2_Click1" />
        </AddressTemplate>
    </address:TemplatedServerAddressControl>
</asp:Content>

ASPXコードビハインド

public partial class TemplatedServerAddress : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        this.addressControl1.Address = "Super Cool";
        this.DataBind();
    }

    protected void Unnamed_Click(object sender, EventArgs e)
    {
        this.Response.Write("From custom button" + DateTime.Now.ToString());
    }

    protected void Unnamed2_Click1(object sender, EventArgs e)
    {
        this.Response.Write("From command button " + DateTime.Now.ToString());
    }
}
  • 正しいイベントで問題なくコントロールのプロパティを設定する方法に注意してください。this.addressControl1.Address = "Super Cool";

  • コントロールがカスタムイベントを処理する方法に注目してくださいthis.Response.Write("From custom button" + DateTime.Now.ToString());

  • そして最後に、何かを実行したいことをコントロールに示すには、次のようにコントロールによって公開されるコマンド名でボタンを作成します。<asp:Button Text="Command bubbled" runat="server" CommandName="DoSomething" OnClick="Unnamed2_Click1" />オプションで、ボタンには、イベントをバブリングする前に処理されるイベントハンドラーを含めることができます。

このコードサンプルを完全に機能するようにGitHubにアップロードして参照しました

于 2012-10-02T18:33:30.627 に答える
0

テンプレート化されたユーザー コントロールはどうですか (テンプレート化されたサーバー コントロールとは対照的に)。

テンプレート化されたユーザー コントロールに関する MSDN チュートリアルがあります: http://msdn.microsoft.com/en-us/library/36574bf6(v=vs.100).aspx

事前定義された ID が必要な場合は、このFindControl()メソッドを使用してテンプレートからコントロールを抽出し、必要なクリック イベントなどを添付できます。

例えば

protected void Page_Init(object sender, EventArgs e)
{
  // if a message template has been defined, check for the reset button
  if(MessageTemplate != null)
  {
    // attempt to grab the reset password button
    Button btnResetPassword = MessageTemplate.FindControl("btnResetPassword ") as Button;

    // if the reset password button has been declared, attach the click event             
    if(btnResetPassword != null)
      btnResetPassword .Click += btnResetPassword_Click;  // attach click event
  }
}

protected void btnResetPassword_Click(object sender, EventArgs e)
{
  // reset password behaviour here
}

上記のコードは完全ではなく、テストもされていませんが、私の言いたいことを理解するためのものです。それがあなたの言いたいことかどうかわかりませんか?

于 2012-10-02T10:59:15.003 に答える