Autor Beitrag
kevinkeegan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27

Win 7 Prof., Win XP Prof
C# (VS 2010 Premium), SQL, PLS/SQL
BeitragVerfasst: Fr 23.12.11 11:47 
Hallo,

ich stehe bei dem Aufbau eines Menü-Panels mit Menü-Button und einer Symbolleiste vor folg. Problem:

Das Form-Menü wird in einem Button (vom Typ ButtonItem : DevComponents.DotNetBar.PopupItem) aufgebaut. Der Menü-Button enthält SubItems vom gleichen Typ, die beschriftet werden, ein Image-Objekt erhalten und ein Click-Event zugewiesen bekommen. In der selben Klasse soll die Methode "ErstelleSymbolLeiste(ButtonItem newBtn)" aus dem ButtonItem einen Button (vom Typ System.Windows.Controls.Button) mit gleichem Image-Objekt und gleichem Click-Event erstellen und einem Symbolleisten-Panel hizufügen. Alles kein Problem bis auf das Click-Event. Wie weise ich dem neuen Button-Objekt die selbe Methode im Click-Event wie dem ButtonItem zu?

Die o.g. Methode sieht bis jetzt so aus:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
protected void AddSymbolLeistenButton(ButtonItem btnItem)
{
    Button newBtn;
    const int heightWidth = 25;

    if (btnItem != null)
    {
        newBtn = new Button();
        newBtn.Name = btnItem.Name;
        newBtn.Tooltip = btnItem.Tooltip;
        newBtn.Size = new Size(heightWidth, heightWidth);
        newBtn.Image = btnItem.Image;
        // TODO: Click-Event kopieren
        //var handler = btnItem.GetType().GetEvent("Click");
        //newBtn.Click += new EventHandler(handler);
        this.SymbolLeiste.Add(newBtn);
    }
}


Danke im Voraus!
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 23.12.11 12:47 
Hallo,

das ist so nicht direkt möglich, da man von außerhalb nicht auf die Liste der abonnierten Eventmethoden zugreifen kann.
Übergib doch einfach deiner Methode die Eventmethode:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
protected void AddSymbolLeistenButton(ButtonItem btnItem, EventHandler onClick)
{
  // ...
  newBtn.Click += onClick;
}
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 23.12.11 13:34 
Der Click Event ist eine Property an der kann man nur eingeschränkt arbeiten. Hätte man das eigentlich EventHandler Feld hinter der Property könnte man einfach zuweisen. Habe das mal mit den Standard Winforms Buttons ausprobiert. Das Backingfield für den Click Event ist (wie alle von Control geerbten Events) äußerst gut versteckt :(

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
FieldInfo fiEvents = typeof(Component).GetField("events", BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo fiEventClickKey = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static);

EventHandlerList list = (EventHandlerList)fiEvents.GetValue(meinButton);
object listEntry = typeof(EventHandlerList).InvokeMember("Find", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, list, new object[] { fiEventClickKey.GetValue(button1) });
FieldInfo fiClickDelegate = listEntry.GetType().GetField("handler", BindingFlags.NonPublic | BindingFlags.Instance);

EventHandler click = (EventHandler)fiClickDelegate.GetValue(listEntry);

andererButton.Click += click;


Zitat:
das ist so nicht direkt möglich


Der Code bestätigt glaube ich die Aussage ;)
kevinkeegan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27

Win 7 Prof., Win XP Prof
C# (VS 2010 Premium), SQL, PLS/SQL
BeitragVerfasst: Fr 23.12.11 14:06 
Zunächst Danke für die Antworten.

@Th69: Das ist klar, die Eventmethoden zu benennen und direkt zuzuordnen, das würde gehen. Aber 1. will ich das nicht (nochmal) hart kodieren und 2., das ist entscheidend, ist der Inhalt des Menüs (ButtonItem's) nicht immer der gleiche, weil Child-Form abhängig und deshalb muss es dynamisch geschehen.

@Ralf Jansen: Deinen Code verstehe ich nicht auf Anhieb, das muss ich mir im Detail anschauen. Es sieht auf jeden Fall relativ viel/kompliziert aus, für das bisschen Funktionalität. Ist denn mein Vorhaben so abwegig?

MfG
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 23.12.11 14:18 
Zitat:
Es sieht auf jeden Fall relativ viel/kompliziert aus, für das bisschen Funktionalität ...


Für Funktionalität die eigentlich nicht da ist! Verstehen kann man den Code eigentlich auch nur wenn man sich den Sourcecode von Button/Control/Component etc. in einem Decompiler (wie z.B. Reflector oder ILSpy) ansiehst und verstehst wie die Events abgelegt werden.

Ich will nicht ausschließen das es eine simple Lösung gibt bezweifle es aber.

Edit : Damit das deutlich wird. Den Code habe ich gepostet um zu zeigen das das kompliziert ist und es sinnvoller ist sich eine andere Lösung auszudenken z.B. wie von user profile iconTh69 angedeutet. Ein solchen Code sollte man in einer produktiven Umgebung nie einsetzen da zuviele Interna des .NET Frameworks verwendet werden die sich (zumindest theoretisch) ändern könnten. Es gibt keine Garantie das das mit jedem Versionsstand des Frameworks funktioniert.
kevinkeegan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27

Win 7 Prof., Win XP Prof
C# (VS 2010 Premium), SQL, PLS/SQL
BeitragVerfasst: Fr 23.12.11 14:36 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Es sieht auf jeden Fall relativ viel/kompliziert aus, für das bisschen Funktionalität ...


Für Funktionalität die eigentlich nicht da ist! Verstehen kann man den Code eigentlich auch nur wenn man sich den Sourcecode von Button/Control/Component etc. in einem Decompiler (wie z.B. Reflector oder ILSpy) ansiehst und verstehst wie die Events abgelegt werden.

Ich will nicht ausschließen das es eine simple Lösung gibt bezweifle es aber.

Edit : Damit das deutlich wird. Den Code habe ich gepostet um zu zeigen das das kompliziert ist und es sinnvoller ist sich eine andere Lösung auszudenken z.B. wie von user profile iconTh69 angedeutet. Ein solchen Code sollte man in einer produktiven Umgebung nie einsetzen da zuviele Interna des .NET Frameworks verwendet werden die sich (zumindest theoretisch) ändern könnten. Es gibt keine Garantie das das mit jedem Versionsstand des Frameworks funktioniert.


Aber wie könnte eine Alternative zu meinem Vorhaben (Click-Event zweier Controls "synchronisieren") aussehen, wenn die (Quell-) Buttons nicht feststehen? Kann ich evtl. etwas im Quell-Button.Tag speichern, worauf ich dann später (in der Methode) zugreifen kann?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 23.12.11 15:15 
Zitat:
meinem Vorhaben (Click-Event zweier Controls "synchronisieren")


Vielleicht den Gedanken aufgeben und einen Schritt zurücktreten. Ich würde nicht auf die Idee kommen 2 Controls in irgendeiner Weise synchronisieren zu wollen. Hört sich für mich als wollte man RAD Designer Funktionalität mit dynamische Controlerstellung mischen. Das geht höchst wahrscheinlich schief gibt häßlichen unwartbaren Code oder man läuft in echte Showstopper. Wenn ich eine dynamische Oberfläche will wo, unter anderem, verschiedene Controls das gleiche oder fast das gleiche erledigen sollen würde ich mir eine dritte controlunabhängige Darstellung ausdenken die die Funktionalität beschreiben und aus dieser dann die beiden Controls erstellen die du im Moment synchronisieren willst.

Ich würde also Vorschlagen das du dir eine Klassenstruktur aus denkst die so Sachen wie Caption, Icon, Events etc. verwaltet und daraus dann Menüs und Symbolleisten generieren.
kevinkeegan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27

Win 7 Prof., Win XP Prof
C# (VS 2010 Premium), SQL, PLS/SQL
BeitragVerfasst: Fr 23.12.11 15:46 
Wie immer das auch heissen mag, was ich vorhabe bzw. wie ich vorgehe, aber eigentlich will ich doch nur dass das gleiche geschieht, wenn ein Menüitem gedrückt wird oder sein korrespondierender Symbolleisten-Button. Also so, wie man es z.B. in Word gewohnt ist. Die nächste "Ausbaustufe" ist dann, mit einem definierten Key wiederum das Gleiche auszuführen, wie man es auch aus Word kennt (z.B. Strg + S).

An einer neuen Klasse soll es nicht liegen. Im schlimmsten Fall muss ich den Symbolleisten-Button in der gleichen Methode erstellen, wie den Menü-Button.

Danke und schöne Weihnachten!