Spędziłem dwa dni z innym kolegą, badając to. Byłem zaskoczony, ponieważ większość rozwiązań omawiających ten problem ma albo złe rozwiązanie, albo rozwiązanie, które działa, jak sądzę, z niewłaściwych powodów.Zadzwoń do RaisePostBackEvent pod niewłaściwą kontrolą
Mamy niestandardowe sterowanie przyciskami, które musi podnieść zdarzenie ServerClick po jego naciśnięciu. Oto zestawione kod:
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();
}
}
W przeglądarce zakończyć kod wykorzystuje dwa z tych przycisków
<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>
Problem: Impreza nie jest podniesione na przycisk akceptacji. Debugowanie ujawnia, że RaisePostBackEvent
jest wywoływane, ale na przycisku Zamknij, który nie ma dołączonej obsługi ServerClick
, więc nic się nie dzieje. Żadne procedury obsługi zdarzeń nie zostaną wywołane.
Uwagi:
- Problemem nie jest widoczne, jeśli istnieje tylko jeden myButton na stronie.
- Jeśli przyciski zostaną zmienione tak, że przycisk akceptacji jest ostatnim na stronie, zacznie działać.
- Przeniesienie przycisków poza znacznikiem formularza powoduje, że zdarzenia działają zgodnie z oczekiwaniami, a obsługa zdarzeń przycisków akceptujących jest wywoływana poprawnie.
- Implementacja
IPostBackDataHandler
i wywołanieRaisePostBackEvent()
zIPostBackDataHandler::RaisePostDataChangedEvent()
powoduje prawidłowe podniesienie zdarzenia na przycisku akceptacji, gdy znajduje się wewnątrz znacznika formularza. - Wywołanie
RegisterRequiresRaiseEvent(btnAccept)
podczas PageLoad tras zdarzeń prawidłowo do przycisku akceptowania.
Pytanie:
Jaki jest prawidłowe rozwiązanie od tych, które działają powyżej? Czy istnieje inne rozwiązanie? Potrzebujemy go do działania w taki sposób, aby wiele przycisków na stronie generowało zdarzenia niezależnego kliknięcia, bez względu na ich kolejność lub pozycję na stronie.
Moje myśli:
- Ten problem wydaje się być omówione tutaj: http://forums.asp.net/t/1074998.aspx?ASP+NET+RaisePostbackEvent+Issues
- Jeden to pozwalają przypuszczać, że nazywając
__doPostback()
z prawidłowym__EVENTTARGET
powinien automatycznie trasa zdarzenie poprawnie przycisku, ale to się nie dzieje w rzeczywistości. Dzieje się tak tylko wtedy, gdy implementujemy równieżIPostBackDataHandler
. Wiele rozwiązań w Internecie zdaje się wskazywać na to, że__doPostback
, UniqueID itp. Jako winowajca, gdy faktycznie wdraża sięIPostBackDataHandler
, to wydaje się, że problem jest pozornie rozwiązany. - Sterownik implementuje
IPostBackEventHandler
, ale nieIPostBackDataHandler
. Myślę, że to jest poprawne, ponieważ kontrola nie musi podnosić żadnych zdarzeń opartych na danych. WdrożenieIPostBackDataHandler
, aby działało, wydaje się być hackerem. - Korzystanie z
RegisterRequiresRaiseEvent
jest niezrozumiałe, a poza tym nie będzie działać, jeśli wiele przycisków na stronie chce podnieść zdarzenia. - Zastanawiam się, jak to robi
asp:Button
?
klasa publiczna MyButton: Button – EJD
@EJD, nie możemy zmienić hierarchii klas – Ali