Ich habe zwei Tage mit einem anderen Kollegen verbracht, der das untersucht hat. Ich war überrascht, dass die meisten Lösungen, die dieses Problem diskutieren, entweder die falsche Lösung oder eine Lösung haben, die aus den falschen Gründen funktioniert.RaisePostBackEvent bei falscher Kontrolle aufgerufen
Wir haben ein benutzerdefiniertes Schaltflächensteuerelement, das ein ServerClick-Ereignis auslösen muss, wenn es gedrückt wird. Hier ist der zusammengefasste Code:
public class MyButton : WebControl, IPostBackEventHandler
{
protected HtmlGenericControl _Button;
protected string _OnClick = "";
protected string _Name;
public event EventHandler ServerClick;
// etc...
public MyButton()
{
Width = Unit.Pixel(100);
_Button = new HtmlGenericControl("button");
Controls.Add(_Button);
}
protected override void Render(HtmlTextWriter writer)
{
_Button.Attributes.Add("id", string.IsNullOrEmpty(_Name) ? base.ID : _Name);
_Button.Attributes.Add("name", _Name);
// etc...
_OnClick = Page.ClientScript.GetPostBackEventReference(this, "");
_Button.Attributes.Add("onClick", _OnClick);
// etc...
ID = String.Empty;
Name = String.Empty;
AccessKey = String.Empty;
TabIndex = -1;
Width = Unit.Empty;
base.Render(writer);
}
protected virtual void OnServerClick()
{
if (this.ServerClick != null)
{
this.ServerClick(this, new EventArgs());
}
}
public void RaisePostBackEvent(string eventArgument)
{
this.OnServerClick();
}
}
Auf dem Browser den Code Endverwendungen zwei diese Tasten
<form>
<!-- etc ... -->
<div class="row actionBar">
<PGSC:MyButton Name="btnAccept" ID="btnAccept" LabelID="3244" TabIndex="70" runat="server" OnServerClick="AcceptClickHandler"/>
<PGSC:MyButton Name="btnClose" ID="btnClose" LabelID="349" OnClick="window.returnValue=frmMMD.hdnMmdId.value;window.close();" TabIndex="80" runat="server" />
</div>
</form>
Das Problem: Die Veranstaltung nicht auf der akzeptieren Taste ausgelöst wird. Debugging zeigt, dass RaisePostBackEvent
aufgerufen wird, aber auf die Schließen-Schaltfläche, die keinen ServerClick
Handler angeschlossen hat, daher passiert nichts. Es werden keine Ereignishandler aufgerufen.
Hinweise:
- Das Problem gesehen wird, nicht, wenn es nur eine MyButton auf der Seite.
- Wenn die Schaltflächen so angeordnet sind, dass die Schaltfläche "Akzeptieren" die letzte auf der Seite ist, beginnt sie zu arbeiten.
- Wenn Sie die Schaltflächen außerhalb des Formular-Tags bewegen, werden die Ereignisse wie erwartet ausgeführt, und der Event-Handler für die Accept-Schaltflächen wird korrekt aufgerufen.
- Das Implementieren von
IPostBackDataHandler
und das Aufrufen vonRaisePostBackEvent()
vonIPostBackDataHandler::RaisePostDataChangedEvent()
bewirkt, dass das Ereignis auf der Schaltfläche "Annehmen" innerhalb des Formular-Tags korrekt ausgelöst wird. - Der Aufruf von
RegisterRequiresRaiseEvent(btnAccept)
während PageLoad leitet Ereignisse korrekt an die Schaltfläche "Annehmen" weiter.
Die Frage:
Was ist die richtige Lösung von denen, die oben arbeiten? Oder gibt es eine andere Lösung? Es muss so funktionieren, dass mehrere Schaltflächen auf der Seite unabhängig von ihrer Reihenfolge oder Position auf der Seite unabhängige Klickereignisse auslösen können.
Meine Gedanken:
- Dieses Problem hier diskutiert zu werden scheint: http://forums.asp.net/t/1074998.aspx?ASP+NET+RaisePostbackEvent+Issues
- Eine Leitung ist zu glauben, dass Aufruf
__doPostback()
mit den richtigen__EVENTTARGET
sollte automatisch Route das Ereignis korrekt auf die Taste, aber Das passiert in Wirklichkeit nicht. Es passiert nur, wenn wir auchIPostBackDataHandler
implementieren. Viele Lösungen auf dem Web scheinen auf__doPostback
, UniqueID usw. als der Übeltäter zu zeigen, wenn die tatsächliche ImplementierungIPostBackDataHandler
ist, was scheinbar das Problem behebt. - Die Steuerung implementiert
IPostBackEventHandler
, aber nichtIPostBackDataHandler
. Ich denke, das ist richtig, da das Steuerelement keine datengesteuerten Ereignisse auslösen muss. Die Implementierung vonIPostBackDataHandler
, damit es funktioniert, scheint wie ein Hack zu sein. - Die Verwendung von
RegisterRequiresRaiseEvent
ist nicht intuitiv und wird außerdem nicht funktionieren, wenn mehrere Schaltflächen auf der Seite Ereignisse auslösen möchten. - Ich frage mich, wie macht ein es?
öffentliche Klasse MyButton: Schaltfläche – EJD
@EJD, wir sind nicht berechtigt, die Klassenhierarchie zu ändern – Ali