SharePointCommunity
Die deutschsprachige Community für SharePoint, Microsoft 365, Teams, Yammer und mit Azure

Sponsored by

Willkommen im Forum Archiv.
Einträge sind hier nicht mehr möglich, aber der Bestand von 12 Jahren SharePoint-Wissen ist hier recherchierbar.




Sozusagen "Concurrent" WebParts (da mehrfach auf selber Page)

Geprüfte Antwort Dieser Beitrag hat 35 Antworten

Ohne Rang
66 Beiträge
Goldfinger erstellt 22 Feb. 2010 10:55
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Hallo Freunde,

ich komme ursprünglich aus der JSF/JSP Ecke und habe vor ca. einem Monat mit SharePoint begonnen. Dazu arbeite ich das Buch "Inside Microsoft WSS 3.0" ab, stoße allerdings häufig auf kleine Unklarheiten bzw. zu ungenau erläuterte Konzepte. Meistens kann ich diese mit Hilfe des WWW und Google finden, dieses mal habe ich allerdings ein etwas weiterführendes konzeptuelles Problem, worauf ich bislang keine Antworten finden konnte.

Damit ich beim Lernen auch noch ein bisschen Produktives tue, habe ich mich dazu entschlossen als "Übungs-Projekt" ein WebPart zur Steuerung von HyperV Maschinen mit Hilfe von WMI zu basteln. Das klappt auch schon alles und wird bald OpenSource sein, falls es jemand brauchen kann.

(Ich kann den Link gerne dann hier reinschreiben.)

So nun zu meinem Problem, das ich als "JSF/JSP-Denker" habe.

In JSF/JSP gab es sogenannte "Request-Beans" mit dessen Hilfe ich Form-Actions Verarbeiten konnte.

z.B. Klick auf Button X in Seite Y erzeugte eine Request-Bean mit Parametern und rief noch eine Methode auf, in der dann alles verfügbar war. Also in SharePoint-Mundart sozusagen eine "Code-Behind"-Klasse, allerdings mit  richtigen von mir spezifizierten Objekten als Übergabeparameter.

In meinem HyperV-WebPart befindet sich eine SPGridView welche mit Rows aus einem WMI-Provider gefüttert wird. Klappt.

In meinem HyperV-WebPart befinden sich pro Row mehrer "ECB-Menu"s (wenn ich das richtig genannt bzw. gelernt habe) um die VM's zu starten/stoppen/snapshotten/etc. Klappt.

Die ECB-Menus sind hard-gecodete MenuItemTemplate Klassen und hatten von mir zunächst eine ClientOnClickNavigateUrl Property gesetzt bekommen, um dann mittels HTTP Request diverse Parameter (VM ID, Action[start/stop/etc.], uvm) bekommen, sodass dann beim nächsten OnLoad() des WebParts entsprechende Vorgänge an die WMI Schnittstelle weitergeleitet werden konnten. Klappt.

Nachdem das alles ok war, habe ich auf der selben Page ein weiteres Hyper-V WebPart hinzugefügt, da wir 2 Hyper-V Systeme haben. Also pro Server ein WebPart auf der selben Page. Klappt.

Dann gingen die Probleme los.

Zunächst einmal haben nun beide WebParts versucht eine angeklickte VM z.B. zu starten (Warum? Beide WebParts haben in der Request URL die Parameter der VM gelesen und angewendet - allerdings ist die VM natürlich nur auf EINEM der beiden Server).

Die Lösung: Im Request zusätzlich noch den Servernamen mitschicken, sodass sich dann in der OnLoad-Methode geprüft werden kann, ob es sich wirklich um den richtigen Server handelt. Falls nicht, wird kein Aufruf an die WMI Schnittstelle geleitet.

Dann dachte ich mir - ist doch schlecht, diletantisch und unsauber. Theoretisch wäre es doch besser, wenn ein richtiges Eventhandler Konzept von vornherein nur das WebPart aufruft, in dem auch geklickt wurde (so würde es JSF/JSP auch tun).

Also habe ich Google angeworfen.

Dort fand ich dann die ClientOnClickUsingPostBackEvent-Property, mit deren Hilfe man ein spezielles Control aufrufen kann.

Dann dachte ich mir - ist doch schlecht, diletantisch, unschön. Ich will einen EventHandler PRO WebPart, nicht PRO Control.

Also versuche ich jetzt jedem WebPart ein Control zu geben, welches dann von allen anderen Controls aufgerufen wird (man landet in der RaisePostBackEvent-Methode).

Dummerweise muss ich dazu eine ID vergeben. Und zwar jedem WebPart ein "sozusagen Event Control" mit eigener ID, sodass die jeweiligen anderen Controls im WebPart dieses finden können.

Das Problem: es scheint, als würden die WebParts default-mäßig die selbe ID bekommen? Kann das sein?

Meine Idee war, dass ich einfach die WebPart ID nehme und einen "_postBackHandler" String als EventControl-ID konkatiniere.

Das geht aber nicht, da wie gesagt beide WebParts wohl die selbe ID bekommen.

Also war meine Zweite Idee, dass ich einfach einen static int hochzähle, um daraus die Konkatination mache. Das geht aber auch nicht, da die Controls JEDES MAL neu angelegt werden, und der INT dann immer der INT+2 ist (bei 2 WebParts).

Also war meine Dritte Idee, dass ich einfach immer bei der ID schon ID+(Anzahl der baugleichen WebParts) setze [das erlaubt dann aber SharePoint nicht, da es zu dem Zeitpunkt ein solches Control ja noch nicht gibt (No Control with such ID found error.....).

 

Insgesamt weiß ich also nicht wirklich weiter, bzw. weiß ich auch nicht, ob das überhaupt der korrekte Ansatz ist.

Was ist der "Best-Practice" Ansatz zur Parameter-Übergabe eines WebParts an den dazugehörigen EventHandler? Gibt es überhaupt "dazugehörige" EventHandler - oder muss man wirklich alles selbst per Request URL machen? Das kann ja kaum der Sinn des SharePoint-Monsters sein...

Alle Antworten

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 22 Feb. 2010 11:30
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ich konnte leider das eigentliche Problem nicht ganz aus dem (recht langen) Text herauslesen. Trotzdem danke für die ausführliche Beschreibung - ist immerhin besser als "Es gibt einen Fehler, wer kann helfen" :-)

Willst Du mit dem Webpart jeweils eine VM verwalten? Oder jeweils einen VM-Host? Gib dem Webpart doch einfach eine Property, die das festlegt. Der Eigenschaftswert wird pro Webpartinstanz gepflegt. Wenn jetzt irgendwie ein Postback ausgelöst wird (z.B. "starte eine VM"), dann prüfts Du die Eigenschaft und Du weißt, welche VM gestartet werden soll..

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 22 Feb. 2010 12:17
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Man - ich hatte schon 'ne Antwort und hab dann aus Versehen auf den Back-Button geklickt. Jetzt muss ich nochmal neu schreiben....also jetzt nochmal in Kurz.

Ich will, dass bei einem Klick in einem WebPart auch NUR dieses WebPart getriggert wird (die Frage ist das WIE).

Bei deinem Ansatz würden ja die WebParts selbst entscheiden, ob der Aufruf wohl für sie bestimmt war oder nicht. Ich glaub aber nicht, dass sich das die Jungs/Mädels von Microsoft das so gedacht haben. Wofür hab ich denn ein SharePoint Monster, wenn nicht genau für solche Tasks.

Meiner Meinung nach, glaube ich stark, dass SharePoint Events dispatchen kann, und zwar sicherlich direkt an entsprechende GUI Controls um diese so zu triggern.

Ich mein, ständig labern die mich in dem Buch mit Model-View-Controller voll, präsentieren primitivste Konzepte auf komplexe Art und Weise, reden SharePoint in den 7. Himmel, aber wenn es um eines der GRUNDLEGENDSTEN DINGE geht, nämlich Navigation zwischen Seiten bzw. Actions und Event Processing, dann soll SharePoint mich im Stich lassen?

Das kann ich mir einfach nicht vorstellen...

 

Also wie gesagt - ich habe die "ClientOnClickNavigateUrl" Property benutzt um den Ansatz zu verfolgen, den du jetzt auch in etwa vorgeschlagen hast. Das führt auch zu einem passablen Ergebnis, aber ich wette, dass das nicht "Best Practice" ist (aus oben genannten Gründen).

Weiterhin habe ich es mit "ClientOnClickPostBackEvent" versucht, was mir eher nach Triggering aussieht, allerdings geht das nur auf Control Ebene. Also jedes Control bekommt eine eigene RaisePostBackEvent Methode. Das ist mir aber zu spezifisch.

Im Prinzip suche ich nach einer RaisePostBackEvent Methode schon direkt für die WebPart Klasse.

 

Wie stößt du denn sonst so irgendwelche Prozesse aus einem WebPart an? Und wie vermeidest du, dass immer gleich mehrere WebParts Requests verarbeiten, die gar nicht für sie gedacht sind, wenn nicht durch eine Art Events?

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 22 Feb. 2010 13:00
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Jetzt mal langsam: wie eine Seite mit Webparts gerendert wird und wie die Events gehandhabt werden, hat erstmal nichts mit SharePoint zu tun. Das ist reines ASP.NET.

Bei einem Postback (oder beim Neuladen der Seite) werden immer alle Controls (und damit auch Webparts) neu aufgebaut. Beim Postback bleibt der ViewState natürlich erhalten sofern nicht deaktiviert.

Da Du die ClientOnClickNavigateUrl überschreibst, kommt das einem Neuladen der Seite gleich. Verwende hier lieber ein serverseitiges Event. Das wird dann auch nur in einem (dem richtigen) Webpart ausgelöst.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 22 Feb. 2010 13:22
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Okay, dann ist das von mir aus eine ASP.NET Geschichte.

Dass beim Postback alle Controls entsprechend eines ViewState's neu aufgebaut werden ist auch stimmig.

Dass das Event letztendlich serverseitig abläuft hatte ich eigentlich sowieso angenommen (mein Browser sieht ja nur HTML - ich bin davon ausgegangen, dass evtl. Event-Manager Klassen aus SharePoint bzw. ASP allerdings durchauch wissen können, wo der Benutzer geklickt hat, um letztendlich dann wieder bei entsprechenden GUI Elementen (bzw. dem ganzen WebPart wäre mir am liebsten) Ereignisse auszulösen.

Ich bin eben davon ausgegangen, dass man mit  ClientOnClickUsingPostBackEvent eben genau das mitteilt, nämlich welche Methode bzw. welches Control letztendlich mit welchen Parameteren aufgerufen bzw. getriggert wird.

Das Überschreiben der ClientOnClickNavigateUrl ist ja genau das, was ich NICHT mehr machen will, weil ich damit ja genau die Funktionalität aus ASP.NET killen würde.

Könntest du mir jetzt evtl. noch einen Link oder Code Sample bzw. beteiligte Klassen/Interfaces für "Serverseitige Events" nennen? Gerne auch in Form eines Links (mit Konzept-Skizzen [welche Klasse regelt was, was läuft ASP.NET intern ab])?

Ich weiß leider nicht wie das "Schlagwort" heißt, so dass ich auch nicht wirklich weiß nach was ich googlen könnte...

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 22 Feb. 2010 13:49
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

OK, Dir ist also klar, warum Du mit dem OnClientClick eben keinen Postback, sondern ein Neuladen auslöst. Nur bei einem Postback kann ein Ereignis auch eindeutig einem Control zugeordnet werden.

Tut mir leid, aber ich habe da keinen passenden Link zur Hand. Mir scheint auch, daß Du Dich schon ziemlich intensiv mit der Materie beschäftigt hast. Da fehlt nicht mehr viel ;-)

Ich kenne jetzt Deine konkreten Lösungsversuche nicht, aber versuche es mit einem "normalen" Hyperlink- oder Menü-Control umzusetzen. Dort findest Du dann auch eine NavigateUrl (ohne Client im Namen) bzw. eine OnServerClick-Eigenschaft. Irgendwas in der Art.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 22 Feb. 2010 14:12
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ich habe jetzt nochmal recherchiert.

Ich würde sagen das "ClientOnClickNavigateUrl" entspricht in etwa einer XML-Deklaration "CustomAction". Da werden auch einfach Attribute in den URL Request gepackt. Wer das dann letztendlich liest und nutzt, entscheiden jede Page bzw. jedes Part für sich. Also keine Events. (Wenn ich das richtig sehe - eben wie du auch gemeint hast, es wird die Seite neu geladen und man muss halt z.B. in OnLoad() oder anderen Zyklus-Stufen selber handeln [oder ignorieren].

Ich halte das eben für den diletantischen Weg, weil THEORETISCH könnte ja SharePoint / ASP.NET Actions, Events, Trigger alles schon selber verwalten.

 

Was ich auf Grund der Recherche jetzt zu brauchen glaube ist Folgendes:

Eine Art CustomActions für Starten, Stoppen, Snapshotten, etc. für meine "MenuItemTemplate"s (jeweils pro Listeneintrag), allerdings in einer Art und Weise, so dass letztendlich eine Art ListenController informiert wird.

Ich glaube für die Standard Actions gibts ja sowas eh schon irgendwie (Edit Row, Sort, Delete Row, etc.).

Gibt es nicht hierfür eine Custom-Lösung? Edit Row, Sort, Delete Row, etc. funktioniert ja sicherlich auch so.

 

Zusätzlich bin ich auf "BubbleEvents" gestoßen:

Evtl. kann man ansonsten mit Hilfe von BubbleEvents die ClientOnClickUsingPostBackEvent (die man ja nur in Verbindung mit konkreten "WebControls" nutzen kann) durch "RaiseBubbleEvent" an den übergeordneten Container ( = das WebPart!) leiten. Dort würde dies dann in der "OnBubbleEvent Methode" münden [wenn ich das richtig sehe].

Dann hätte man evtl. auch sowas wie einen PostBack auf WebPart Ebene? Ob das wohl funktionieren könnte, bzw. ob es überhaupt Sinn macht?

Ohne Rang
929 Beiträge
Thomas Östreich Als Antwort am 22 Feb. 2010 14:29
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

ich hänge mich mal mit rein.

Ein (Asp.Net) WebPart besitzt "INamingContainer" und bekommt auf dem Client immer eine eindeutige ID um so auf ServerEvents zu reagieren.
ParentContainer1_ParentContainer[n]_Child

Wenn ich nun in meinen WebPart Asp.Net oder SharePoint WebControls hoste (diese haben auch einen INamingContainer) kann ich mich über deren ServerEvents benachrichtigen lassen egal wie oft das Control / WebPart auf der Page vorhanden ist. Du muss halt im UserState deine besonderen Unterschiede speichern und beim Postback auslesen, diese informationen kann man auch in ein Hiddenfield speichern.

Wichtig: Asp.Net und SharePoint Controls implementieren INamingContainer so das die ID immer die des Parents vorangestellt wird und reine HTML Controls diese Eigenschaft nicht besitzen!

Gruß Thomas

Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 22 Feb. 2010 14:44
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Und wie genau kann ich mich an die Events der Controls ranhängen?

Bzw. am liebsten würde ich die Frage so formulieren (falls ich das richtig verstanden habe):

D.h. ich füge für jedes Control jeweils ClientOnClickUsingPostBackEvent hinzu, sodass (je nachdem wo der Benutzer klickt) auf dem entsprechenden Control wiederum die RaisePostBack Methode mit den dazugehörigen argumenten aufgerufen wird.

Um dann innerhalb der RaisePostBack Methode des jeweiligen Controls doch wieder eine Methode des ParentContainer aufzurufen (wozu wohl ein Cast nötig wird).

Wie würde der Code ungefähr aussehen - welche Properties, Methoden/Interfaces müssen zur Hilfe genommen werden? Wäre es so wie ich gerade beschrieben habe?

Ohne Rang
929 Beiträge
Thomas Östreich Als Antwort am 22 Feb. 2010 15:13
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Asp.Net Controls besitzen Events z.B System.Web.UI.WebControls.Button [Click] , ListBox [SelectedIndexChanged] hast du diese Controls in deinen WebPart kannst du in CreateChildControls dich beim anlegen dieser Controls an deren Events binden (button.Click += ....) so das dann deine Methode bei Click aufgerufen wird.

JSP Migration: http://msdn.microsoft.com/en-us/library/aa185926.aspx
Page Life cycle: http://msdn.microsoft.com/en-us/library/ms178472.aspx
                              http://msdn.microsoft.com/en-us/library/ms972976.aspx
WebPart Life cycle: http://msdn.microsoft.com/en-us/library/ms366536.aspx

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 22 Feb. 2010 15:34
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Du brauchst die ganzen genannten Methoden gar nicht zu überschreiben. ASP.NET erledigt das alles für Dich.

Ich weiß jetzt gerade nicht, wie das vom GridView-Menü gehandelt wird, aber normalerweise bindest Du einfach den Click-Ereignishandler an eine passende Methode und gut ist.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 22 Feb. 2010 15:36
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Genau das, genau das! "Einfach einen 'Click-Ereignis-Handler' - so stelle ich es mir vor!

Das Problem: Die Klasse "MenuItemTemplate" biete so etwas nicht. Es gibt keine "OnClick" oder "ClickEvent" Property oder sonst etwas derartiges.

 

Jetzt versteht man mich langsam.......    :-)

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 22 Feb. 2010 15:39
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Aber irgendwo definierst Du doch die eigentlichen MenuItems? Wie gesagt, ich habe dieses Menü gerade nicht im Kopf...

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 22 Feb. 2010 15:45
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Definiert wird das so (jedenfalls siehts bei mir so aus:

 

 

SPMenuField

 

 

 

colMenu = new SPMenuField();

colMenu.HeaderText = 

 

"System";

colMenu.TextFields = 

 

"System";

colMenu.MenuTemplateId = 

 

"SystemListMenu";

colMenu.NavigateUrlFields = 

 

"System";

colMenu.NavigateUrlFormat = 

 

"?system={0}";

colMenu.TokenNameAndValueFields = 

 

"EDIT=System";

colMenu.SortExpression = 

 

"System";

 

 

 

 

 

 

 

--

 

MenuTemplate

 

 

 

systemListMenu = new MenuTemplate();

systemListMenu.ID = 

 

"SystemListMenu";

 

--

MenuItemTemplate

 

 

 

startMenu = new MenuItemTemplate("Start", "~/_layouts/images/enabled.png");

//Hier kann man z.B. startMenu.ClientOnClickUsingPostBackEvent = "system=%EDIT&action=start&..."; machen

--

systemListMenu.Controls.Add(startMenu);

this

 

 

 

.Controls.Add(systemListMenu);

oGrid.Columns.Add(colMenu);

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 22 Feb. 2010 15:53
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Jetzt wollte ich das doch wissen... Das hier sollte Dir helfen:
http://blog.sdbonline.com/blog/post/Handling-Postbacks-using-MenuItemTemplate.aspx

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 22 Feb. 2010 15:57
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Sieht also doch stark nach einem GeHacke aus...ich schaus mir morgen mal noch an...muss jetzt leider los.

 

Danke schonmal!!!

Sehr nett - das war jetzt aber auch wirklich eine schwere Geburt :-D

 

Grüße!

 

PS: Ich bin ab jetzt öfter hier :-)

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 22 Feb. 2010 16:12
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

[quote user="Goldfinger"]PS: Ich bin ab jetzt öfter hier :-)[/quote]

Gerne, zumal Du ja inzwischen auch Fragen beantwortet hast. Außerdem bist Du ja jetzt bei der "richtigen" Technologie angekommen ;-)

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 23 Feb. 2010 09:25
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Also ich hab mir das jetzt mal sehr lange angeschaut und versucht in die PostBackEventMenuItem-Klasse in mein WebPart zu integrieren und zu nutzen.

Es funktioniert nicht:

  • Das erste Problem war, dass die Control ID's noch NULL waren, sodass ClientOnClickUsingPostBackEventFromControls(this) nicht funktionierte...
  • Lösung: Ich verwalte meine ID's jetzt selbst

Aktuelles Problem:

  • Es wird nicht mal das Event ausgelöst, d.h. ich komme sozusagen niemals in die ~"HandleEvent" Methode.

Ich muss dazu sagen, dass ich mein WebPart nur als C#-Klasse realisiere und nicht die deklarative XML Sprache nutze. Hat es evtl. etwas mit dem "AutoEventWireUp" Attribut zu tun?

 

Eventuell weiteres Problem:

  • So wie ich das sehe wird nur ein Event ausgelöst. Es werden allerdings keine Parameter mitgegeben. Ich schlage also vor, ich erstelle noch eigene "PostBackEventArgs : EventArgs" um diese dann generisch i.V.m. "EventHandler<T>" zu nutzen. Dann könnte man jedem Item im Konstruktor noch Argumente mitgeben.

 

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 23 Feb. 2010 10:11
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Das sollte passen, aber es hat noch etwas mit dem Page Lifecycle zu tun. Die IDs solltest Du ohnehin selbst verwalten, nur die Client-IDs sind z.B. in OnInit noch nicht vergeben.

[quote user="Goldfinger"]Ich schlage also vor, ich erstelle noch eigene "PostBackEventArgs : EventArgs" um diese dann generisch i.V.m. "EventHandler<T>" zu nutzen[/quote]

Genauso ist das gedacht.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 23 Feb. 2010 10:26
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Aber auch wenn ich die ID's selbst verwalte wird das Event nicht ausgelöst....die Page wird neu geladen, aber er kommt niemals in "RaisePostBackEvent"....

Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 23 Feb. 2010 10:41
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Also wenn ich nur einen einzigen Menü-Eintrag für "Virtuelle Maschine starten" mache, dann wird gepostbacked und die RaisePostBackEvent Methode wird aufgerufen....

Sobald ich mehrere Einträge hatte war dies nicht mehr der Fall :-(

Ohne Rang
929 Beiträge
Thomas Östreich Als Antwort am 23 Feb. 2010 10:47
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Mach es doch über ClientOnClickNavigateUrl und übergebe deine Parameter auch die Source dann kannst du über SPUtility.Redirect wieder zur Page zurückgehen.

Du musst dann aber wenn du Änderungen in SharePoint machst diese für ein GET erlauben (SPWeb.AllowUnsafeUpdates).
Desweiteren kannst du dann auch gut  SPLongOperation für längerdauernde aktionen nutzen.

Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 23 Feb. 2010 10:51
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Aber genau das will ich nicht.

So habe ich es ja schon hinbekommen. Das halte ich aber für unsauber. Siehe Vordere Beiträge. (Danke trotzdem!)

 

Ich will es als PostBack haben, so würde es sich gehören - bei primitiveren Controls klappts ja auch!

Ohne Rang
929 Beiträge
Thomas Östreich Als Antwort am 23 Feb. 2010 11:12
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Also für das Postback benötigst du die this.UniqueID deines WebParts hier mal etwas code wie das mit JavaScript erreicht wird:

deleteMenuItemTemplate.ClientOnClickScript =

"javascript:confirmDelete('" + this.UniqueID + "','%PRODUCT%','%SITEID%');";

function
confirmDelete(ID,ProductName,siteId){
 
if (confirm("<SharePoint:EncodedLiteral runat='server' Text='<%$Resources:LicAdmin, dellic_warning%>' EncodeMethod='EcmaScriptStringLiteralEncode'/>")) {
   __doPostBack(ID,ProductName+
";"+siteId);
 }
}

Benutze mal http://msdn.microsoft.com/en-us/library/ms457859.aspx und das Control ist dein WebPart. Sollte eigentlich funktionieren, da das WebPart dann IPostBackEventHandler Implementieren muss und WebPart auch von Control erbt.

 

Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 23 Feb. 2010 11:31
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

[quote user="Thomas Östreich"]

Benutze mal http://msdn.microsoft.com/en-us/library/ms457859.aspx und das Control ist dein WebPart. Sollte eigentlich funktionieren, da das WebPart dann IPostBackEventHandler Implementieren muss und WebPart auch von Control erbt.

[/quote]

Genau das ist der Knackpunkt........das klappt nicht ohne Weiteres....

Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 23 Feb. 2010 11:32
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Nämlich, wenn man 2 mal das selbe WebPart added....dann werden irgendwie Parameter vermischt :-S

Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 23 Feb. 2010 11:54
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Szenario:

Ich habe 2 WebParts für jeweils eine HyperV Maschine.

Auf Maschine A läuft VM U und V

Auf Maschine B läuft VM P und Q

User klickt in WebPart A bei VM U auf ECBMenüeintrag "starten". (Mehrere ECB Menüeinträge (je für Start, Stop, Pause, Snapshot) pro SPGridView-Row)

 

Code:

Ich nutze das selbst implementierte "PostBackMenuItemTemplate" (siehe Links in diesem Topic) i.V.m. im WebPart gesetztem PostBackVerhalten z.B. für das Starten von VM's - das sieht dann im WebPart so aus:

 

PostBackEventMenuItem startMenu = new PostBackEventMenuItem("Start", ServerName, "~/_layouts/images/enabled.png");

systemListMenu.Controls.Add(startMenu);

startMenu.ClientOnClickUsingPostBackEvent = startMenu.ID + ", system=%EDIT%&action=start";

startMenu.OnPostBackEvent += new EventHandler<PostBackEventArgs>(OnPostBackItem);

Verhalten:

  • Beim Klick auf das PostBackEventMenuItem wird dann auch ein PostBack ausgeführt und die im PostBackEventMenuItem implementierte RaisePostBackEvent Methode wird aufgerufen.
  • Die RaisePostBackEvent Methode informiert NUR das WebPart B (statt zumindest beide, wobei NUR A richtig wäre)
  • In WebPart bzw. Maschine B gibt es natürlich keine VM U, sodass weitere WMI Aufrufe fehlschlagen.

Das Problem:

  • Obwohl in WebPart A geklickt wird, wird einzig WebPart B aufgerufen
Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 23 Feb. 2010 11:57
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Anmerkung:

Witzigerweise ist die Reihenfolge der EventHandler Registrierung sogar noch verkehrt herum. Es wird zuerst Handler für B registriert, und dann der Handler von A.

D.h. also, dass es auch nicht unbedingt an sowas wie "A überschreibt B" liegen kann, weil dann wäre beim späteren Aufruf ja auch wenigstens wieder Klick auf A informiert A (und nicht NUR B!)

Ohne Rang
929 Beiträge
Thomas Östreich Als Antwort am 23 Feb. 2010 12:41
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Schau mal auf dem Client mit den IE8 Entwicklertools ob den die ID's innerhalb des Webpart nicht uniqe sind also nicht den aufbau haben ParentId_ParentId[n]_clientId. Dort solte man dann auch den Javascript Code sehen der das Postback auslöst. Ich gehe sehr stark davon aus das die ID's zwischen den WebParts identisch sind.

Benutze mal die Methode ClientOnClickUsingPostBackEventFromControl vom MenuItemTemplate

Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 23 Feb. 2010 16:03
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

HTML Ausschnitt von WebPart für Maschine "HyperV1":

<td title="HyperV1" id="WebPartTitleWPQ8"....

Bei entsprechendem Menü-Eintrag steht im HTML:

<ie:menuitem id="zz13_Start~HyperV1" type="option" iconSrc="~/_layouts/images/enabled.png" onMenuClick="__doPostBack('ctl00$m$g_85cef8c4_bc37_441a_8b31_a782902911a1$Start~HyperV1',' system=%EDIT%&amp;action=start')"

(ID's werden selbst verwaltet und kommen offentsichtlich ordentlich an [ ..."Start~HyperV1"])

HTML Ausschnitt von WebPart für Maschine "HyperV2":

<td title="HyperV2" id="WebPartTitleWPQ7" ...

Und auch hierfür ein Beispiel-Menüeintrag:

<ie:menuitem id="zz17_Start~HyperV2" type="option" iconSrc="~/_layouts/images/enabled.png" onMenuClick="__doPostBack('ctl00$m$g_a747127d_906c_425f_bcd9_e3aa780baaca$Start~HyperV2',' system=%EDIT%&amp;action=start')"

Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 23 Feb. 2010 16:23
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

zzXX kommt deshalb, weil ich "UseShortID=true" habe....normalerweise ist das ein ewig langer Klotz aus GUIDs - aber auch DANN kommt es letztendlich zur Vermischung (hat also mit "UseShortID" nichts zu tun...)

Ohne Rang
929 Beiträge
Thomas Östreich Als Antwort am 23 Feb. 2010 16:27
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Hast du 'ctl00$m$g_85cef8c4_bc37_441a_8b31_a782902911a1$Start~HyperV1'..  den Eintrag (ID) auch im client gefunden? Denn das ist die UniqeID woran im Postback das richtig Control erkannt wird.

Nutzen den auch jedes WebPart sein ie:MenuItem (ID, onkeydown, onfocus, ...) 

Ich vermute irgendwie das du da noch irgenwo einen anderen Fehler hast.

Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 24 Feb. 2010 08:18
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Das ist z.B. der Button, der im WebPart ->2<- eine Spalte sortiert (z.B. hier jetzt die "System"-Spalte):

javascript:__doPostBack('ctl00$m$g_a747127d_906c_425f_bcd9_e3aa780baaca$ctl02','Sort$System'

Ich würde sagen das entspricht genau der ID, die das WebPart 2 oben auch bei meinen ECB Einträgen hatte....

Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 22 Feb. 2010 14:20
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Eine "OnServerClick" Eigenschaft konnte ich nicht ausfindig machen :-(

Wie würde denn ein "normaler" Hyperlink anders machen als mein ECB Menü Eintrag? Der ECB Menü Eintrag ist doch letztendlich auch nur ein Link - im Browser kommt ja nur HTML an - der ECB Menü-Eintrag kann wohl nur Link oder Form Submit Button sein...bzw. JavaScript Auslöser....

Was genau meinst du mit "Menü-Control" ? Ich habe halt im SPGridView jeder Row mehrere "MenuItemTemplate" (Start,Stop, Snapshot,...) einem "SPMenuField" zugeordnet. Früher hätte man gesagt: ComboBox mit Items, wobei jedes Item eine Action darstellt....bei normalen Applikation würd ich da jetzt einfach jedem Item ein "OnClickEvent" anhängen...Im Web muss man aber eben entweder die Zyklen einhalten ODER (und das ist der Knackpunkt)ASP.NET/SharePoint die Events managen lassen.....der kennt ja alle Controls, alle Klasse, alle Methode, alle GUID's.....

Ohne Rang
66 Beiträge
Goldfinger Als Antwort am 24 Feb. 2010 09:44
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ich habe jetzt eine zusätzliche Spalte in der DataSource gemacht "SystemName". Diese wird nicht angezeigt, sondern dient quasi als "HIDDEN FIELD", welches beim PostBack mitgesendet wird (neben der Action und dem VM Namen).

Nun übernimmt eben irgendein VM-WebPart (keine Ahnung nach welcher Art das in SP entschieden wird...) die Funktion, auf Server X bei VM Y die Aktion Z auszuführen.

Ist zwar mies, aber irgendwie kann ich jetzt auch nicht noch 42 Tage dransitzen an soner (eigentlich) Kleinigkeit!

 

Danke trotzdem für eure Hilfen!