Laden...

[gelöst] Button zur Laufzeit via Code aktivieren

Erstellt von Toem99 vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.066 Views
T
Toem99 Themenstarter:in
511 Beiträge seit 2008
vor 14 Jahren
[gelöst] Button zur Laufzeit via Code aktivieren

Hallo,
ich durchlaufe alle meine offenen Fenster und prüfe via Code die darin enthaltenen Controls. Habe ich nun ein Control namens btnOk im Fenster, möchte ich diesen zur Laufzeit "klicken".

Wie kann ich das am einfachsten realisieren?

foreach (Form child in this.MdiParent.MdiChildren)
            {
                Console.WriteLine(child.Name);

                foreach (Control ctrl in child.Controls)
                {
                    Console.WriteLine(ctrl.Name);
                    if (ctrl.Name == "btnOk")
                    {
                        ... hier der Code der den Button klicken soll
                    }
                }
            }

Nicht für das Leben, für die Arbeit lernen wir ...
Windows ist Klasse, ich nehme es um Linux zu downloaden ....

1.665 Beiträge seit 2006
vor 14 Jahren

Wozu klicken? Willst du nicht eher eine bestimmte Methode ausführen? Wozu brauchst du also den Button?

Button.PerformClick();
T
Toem99 Themenstarter:in
511 Beiträge seit 2008
vor 14 Jahren

Schon, nur das ich eben nicht weiss, ob sich dieser Button im geprüften Fenster überhaupt befindet.

Nicht für das Leben, für die Arbeit lernen wir ...
Windows ist Klasse, ich nehme es um Linux zu downloaden ....

A
254 Beiträge seit 2007
vor 14 Jahren

Hi,

aber nachdem Du mit dem von Dir geposteten Code-Abschnitt herausgefunden hast, ob es den Button gibt, kannst Du ja die Methode, wie JunkyXL geschrieben hat, aufrufen.

Oder hast Du etwas ein ganz anderes Problem und keiner versteht Dich ?

T
Toem99 Themenstarter:in
511 Beiträge seit 2008
vor 14 Jahren

Ne, schon gut. Ich habs jetzt via

foreach (Control ctl in ctrl.Controls)
{
       ....
       Button btn = new Button();
       btn = (Button)ctl;
       btn.PerformClick();
}

umgesetzt und es läuft. Danke.

Nicht für das Leben, für die Arbeit lernen wir ...
Windows ist Klasse, ich nehme es um Linux zu downloaden ....

916 Beiträge seit 2008
vor 14 Jahren

Das ist aber ziemlich dirty. Wieso legst du erst ein Button an den du dann wieder überschreibst. Deutlich besser wäre folgendes (is & as) Operator.


if (ctl is Button)
{
    ((Button)ctl).PerformClick();
}

oder


Button btn = ctl as Button;
if (btn != null)
{
    btn.PerformClick();
}

Beides geht, wobei mir das erstere besser gefällt. Ist aber Geschmacksache.

Again what learned...

T
Toem99 Themenstarter:in
511 Beiträge seit 2008
vor 14 Jahren

Hab ich gar nicht so drüber nachgedacht. Habs aber jetzt wie bei Dir im Step 1 geändert.

Danke

Nicht für das Leben, für die Arbeit lernen wir ...
Windows ist Klasse, ich nehme es um Linux zu downloaden ....

1.820 Beiträge seit 2005
vor 14 Jahren

Hallo!

@rollerfreak2:
Obwohl die erste Variante kürzer ist, ist die zweite vorzuziehen. Der Grund ist, dass in der ersten Variante zwei Casts durchgeführt werden (einmal durch den is-Operator und dann durch den expliziten Cast), während in der zweiten Variante nur ein Cast und eine Überprüfung des Ergebnisses durchgeführt wird.

Einige Tools, wie z.B. Resharper, bemängeln dies sogar bei ihren Überprüfungen.

Nobody is perfect. I'm sad, i'm not nobody 🙁

916 Beiträge seit 2008
vor 14 Jahren

Danke Tom. Du hast recht, der IL Code ist braucht länger. Aber das erste sieht schöner aus 😉

Leider kostet eine Resharper Lizens viel Geld 😦

Again what learned...

2.891 Beiträge seit 2004
vor 14 Jahren

Obwohl die erste Variante kürzer ist, ist die zweite vorzuziehen. Der Grund ist, dass in der ersten Variante zwei Casts durchgeführt werden (einmal durch den is-Operator und dann durch den expliziten Cast), während in der zweiten Variante nur ein Cast und eine Überprüfung des Ergebnisses durchgeführt wird.

Oh oh, dass kann man aber nicht so stehen lassen - weil es einfach falsch ist.


    L_0000: ldarg.1 
    L_0001: isinst [System.Windows.Forms]System.Windows.Forms.Button
    L_0006: brfalse.s L_0013
    L_0008: ldarg.1 
    L_0009: castclass [System.Windows.Forms]System.Windows.Forms.Button
    L_000e: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Button::PerformClick()
    L_0013: ret 

.locals init ([0] class [System.Windows.Forms]System.Windows.Forms.Button btn)
    L_0000: ldarg.1 
    L_0001: isinst [System.Windows.Forms]System.Windows.Forms.Button
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: brfalse.s L_0010
    L_000a: ldloc.0 
    L_000b: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Button::PerformClick()

Wie man sieht, wird das gleiche gemacht. Zuerst kommt (in beiden Varianten!) ein isinst, wenn die Prüfung positiv war, wird das Control gecastet (in der as-Variante durch das storelocal abgedeckt) und dann die entsprechende Methode aufgerufen.
In der is-Variante wird also gar nicht "zu viel" gecastet. Stattdessen wird in der as-Variante zu viel geladen/gespeichert, zudem muss extra eine lokale Varaible angelegt werden.

Also wenn schon für Sprachkonstrukte aufgrund von erzeugtem IL-Code entscheiden, dann doch schon wegen der richtigen Gründe. Da das aber eh totaler Unsinn ist (hallo, das "I" in IL heißt "Intermediate"!), sollte man sich viel lieber für die lesbarere Variante entscheiden.

Gruß,
dN!3L