Пользовательский серверный элемент управления ASP.Net не запускает пользовательское событие - PullRequest
0 голосов
/ 12 октября 2011

Я создал пользовательский серверный элемент управления. Он выглядит великолепно, и отображаемый HTML-код также должен быть. У меня изначально было расширение ControlContainer, а теперь он расширяет WebControl (оба ведут себя одинаково). У него есть два свойства, ImageUrl и Text. По сути, он будет отображать общий тег HTML с тегами and и внутри него.

Моя проблема в том, что выставленное событие ServerClick (по NamingContainer, я верю), похоже, не сработало. Если я добавлю любую из кнопок ASP («Ссылка», «Изображение» или «Обычный») и свяжусь с этим событием Click, оно будет запущено, но, конечно, у меня будет дополнительный визуализированный контент. Он успешно запускает JavaScript и выполняет вызов __dopostback. Но он не должен видеть данный идентификатор элемента управления или что-то еще, потому что событие никогда не запускается.

using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace PLSO.Info.Web.UI {

[DefaultEvent("Submit")]
[DefaultProperty("Text")]
[ToolboxData("<{0}:ComboButton runat=\"server\"> </{0}:ComboButton>")]
public class ComboButton : WebControl {

    private HtmlImage imageControl;
    private HtmlGenericControl spanControl;

    private static readonly object EventSubmitKey = new object();

    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("")]
    [Description("The text to display on the button.")]
    public string Text {
        get { return ViewState["NewText"] as string; }
        set { ViewState["NewText"] = value; }
    }

    [DefaultValue("")]
    [Bindable(true)]
    [Category("Appearance")]
    [UrlProperty()]
    [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
    public string ImageUrl {
        get {
            EnsureChildControls();
            return this.imageControl.Src;
        }
        set {
            EnsureChildControls();
            this.imageControl.Src = value;
        }
    } // ImageUrl - Property

    public override string CssClass {
        get { return ViewState["CssClass"] as string; }
        set { ViewState["CssClass"] = value; }
    }

    [Category("Action")]
    [Description("Raised when the user clicks the button.")]
    public event EventHandler Submit {
        add { Events.AddHandler(EventSubmitKey, value); }
        remove { Events.RemoveHandler(EventSubmitKey, value); }
    }

    protected virtual void OnSubmit(EventArgs e) {
        EventHandler SubmitHandler = (EventHandler)Events[EventSubmitKey];

        if (SubmitHandler != null)
            SubmitHandler(this, e);
    }

    void ComboButton_Submit(object sender, EventArgs e) {
        OnSubmit(EventArgs.Empty);
    }

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

        imageControl = new HtmlImage();
        imageControl.Src = this.ImageUrl;
        imageControl.Alt = this.Text;
        this.Controls.Add(imageControl);

        spanControl = new HtmlGenericControl("span");
        spanControl.InnerText = this.Text;
        this.Controls.Add(spanControl);

        this.Submit += new EventHandler(ComboButton_Submit);

        ChildControlsCreated = true;
    }

    protected override void Render(HtmlTextWriter writer) {
        PostBackOptions pbo = new PostBackOptions(this);

        AddAttributesToRender(writer);
        writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
        writer.AddAttribute("onclick", string.Format("javascript:{0}", Page.ClientScript.GetPostBackEventReference(pbo)));
        writer.RenderBeginTag(HtmlTextWriterTag.Button);
        imageControl.RenderControl(writer);
        spanControl.RenderControl(writer);
        writer.RenderEndTag();
    }
    }
}

Вот моя разметка. Я вставил этот элемент управления, а затем обычный ASP: кнопку. Это событие обычной кнопки получает удар! Не мое.

<ucs:ComboButton ID="btnT4" runat="server" Text="Please" CssClass="PButtonCombo" ImageUrl="~/Styles/icons/edit-find.png" OnSubmit="btnT4_Submit" />
<asp:Button ID="btnT5" runat="server" Text="TEST" onclick="btnT5_Click" UseSubmitBehavior="False" />

А вот представленный HTML:

* * 1010

Я должен верить, что я близко, но что-то упустил Прошло уже несколько часов, ПОЖАЛУЙСТА, ПОМОГИТЕ!

EDIT

Благодаря ответу @James все, что я сделал, это добавил следующее в начало приведенного выше примера. Он добился цели, но теперь стреляет дважды. Не уверен почему? Это мой текущий вопрос:

public class ComboButton : WebControl, IPostBackEventHandler {

    public void RaisePostBackEvent(string eventArgument) {
        OnClick(new EventArgs());
    }

    [Category("Action")]
    [Description("Raised when the user clicks the button.")]
    public event EventHandler Click;

    protected virtual void OnClick(EventArgs e) {
        if (Click != null)
            Click(this, e);
    }

РЕДАКТИРОВАТЬ 2 == РЕШЕНИЕ

using System.ComponentModel;
using System.Drawing.Design;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace PLSO.Info.Web.UI {

[DefaultEvent("Submit")]
[DefaultProperty("Text")]
[ToolboxData("<{0}:ComboButton runat=\"server\"> </{0}:ComboButton>")]
public class ComboButton : Button {

    private HtmlImage imageControl;
    private HtmlGenericControl spanControl;

    [DefaultValue("")]
    [Bindable(true)]
    [Category("Appearance")]
    [UrlProperty()]
    [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
    public string ImageUrl {
        get {
            EnsureChildControls();
            return this.imageControl.Src;
        }
        set {
            EnsureChildControls();
            this.imageControl.Src = value;
        }
    } // ImageUrl - Property

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

        imageControl = new HtmlImage();
        imageControl.Src = this.ImageUrl;
        imageControl.Alt = this.Text;
        this.Controls.Add(imageControl);

        spanControl = new HtmlGenericControl("span");
        spanControl.InnerText = this.Text;
        this.Controls.Add(spanControl);

        ChildControlsCreated = true;
    } // CreateChildControls - Method - Override

    protected override void Render(HtmlTextWriter writer) {
        PostBackOptions pbo = new PostBackOptions(this);

        AddAttributesToRender(writer);
        writer.RenderBeginTag(HtmlTextWriterTag.Button);
        imageControl.RenderControl(writer);
        spanControl.RenderControl(writer);
        writer.RenderEndTag();
    } // Render - Event - Override
  }
}

Ответы [ 2 ]

3 голосов
/ 12 октября 2011

Попробуйте реализовать интерфейс IPostBackEventHandler:

public class ComboButton : WebControl, IPostBackEventHandler  
{
    public void RaisePostBackEvent(string eventArgument)
    {
        OnSubmit(EventArgs.Empty); 
    }
}

Вот статья, которая объясняет реализацию интерфейса IPostBackEventHandler:http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackeventhandler.aspx

EDIT

Если ваши события каким-то образом зависят от данных, вам необходимо реализовать интерфейс IPostBackDataHandler.Например, вы бы использовали интерфейс IPostBackDataHandler для запуска события OnTextChanged TextBox:

public class ComboButton : WebControl, IPostBackDataHandler  
{
    public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
    {
        return true;
    }

    public virtual void RaisePostDataChangedEvent()
    {

    }
}

Вот статья, которая объясняет реализацию интерфейса IPostBackDataHandler:http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackdatahandler.aspx

2 голосов
/ 12 октября 2011

Вам нужно заглянуть в IPostBackEventHandler

Если вы не реализуете этот интерфейс в вашем контроле, движок ASP.net не будет пересылать события вашему контролю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...