Frage

Ich habe eine Reihe von Tasten, die alle das gleiche Verfahren, jedoch mit dem Index der Schaltfläche als Argument nennen werden.

using System;
using Gtk;

public class Input : Gtk.Window {

    private Gtk.Button[] plus;

    public Input() : base(Gtk.WindowType.Toplevel) {

        plus = new Button[10];

[...]

        for (uint i = 0; i < 10; i++) {
            plus[i] = new Button();
            plus[i].Name = i.ToString();
            plus[i].ButtonPressEvent += AddButtonPressed;
        }
    }

Ich habe versucht, es mit dieser Methode, aber es scheint es nicht einmal, da es aufgerufen wird, erfolgt keine Ausgabe:

    protected virtual void AddButtonPressed(object sender, System.EventArgs e) {
        Console.WriteLine("Button pressed");
        for (uint i = 0; i < plus.Length; i++) {
        if (sender.Equals(plus[i])) {
            uint index = i;
            i = (uint)plus.Length;
            Console.WriteLine(index);
        }
    }

Vielleicht kann mir jemand in die richtige Richtung? Danke.

War es hilfreich?

Lösung

Kurze Antwort:

[GLib.ConnectBefore]
protected virtual void AddButtonPressed(object sender, EventArgs e)     {
    Console.WriteLine("Button pressed");
    for (uint i = 0; i < plus.Length; i++) {
        if (sender.Equals(plus[i])) {
        uint index = i;
        i = (uint)plus.Length;
        Console.WriteLine(index);
        }
    }
}

Rambling Erklärung:

Dies ist tatsächlich eine interessante Frage. Es dauerte ein wenig zu finden suchen, aber GTK # 's FAQ ( aber ich denke nicht häufig verbunden mit) sagt:

  

"Ab Release 0.15, begann Gtk #   unter Verwendung des Flags, wenn CONNECT_AFTER   Ereignishandler Signale.   Dies bedeutet, dass die Event-Handler sind   erst nach dem Standardsignal laufen   Handler, das bedeutet, dass das Widget   wird aktualisiert, wenn das Ereignis   Handler laufen. Ein Nebeneffekt davon   Änderung ist, dass in dem Fall, in dem   Standard-Handler return true zu stoppen   Signal propogation, Ereignisse Gtk # wird   nicht emittiert werden. Dies ist der Fall für   Beispiel in Gtk.Button, wo die   Tastendruck-Ereignis Standardsignal   Handler außer Kraft gesetzt Gepresste auszusenden   Veranstaltungen.

     

Während potenziell verwirrend, ist dies   nicht wirklich ein Problem. Wenn Sie eine   Gtk.Button, Sie bekommen ein Widget   dass emittiert Pressed Ereignisse in Reaktion   BUTTON1 drückt. Wenn Sie auch wollen   Ihre Button Farben zu ändern, oder Popup   ein Kontextmenü auf Button3 Pressen,   das ist kein Gtk.Button. Die richtige   Weg, ein solches Widget zu implementieren ist,   Unterklasse Gtk.Button und überschreiben die   OnButtonPressEvent virtuelle Methode zu   implementieren Sie die neuen Verhaltensweisen   Wunsch. "

Wenn es nicht für waren „öffentlichen Aufschrei“ (selten ein Zeichen für eine gute Schnittstelle), gäbe es keine Möglichkeit, dies zu vermeiden, es sei denn, die Unterklassen in C # manchmal ärgerlich ist aufgrund des Fehlens von anonymen Klassen. Aber zum Glück, du bist nicht die erste Person, um dieses Problem zu haben. Also das ist, wo das GLib.ConnectBefore Attribut kommt in. Es im Grunde sagt, rufen Sie diese Event-Handler zuerst so dass die Veranstaltung nicht von Gtk + verschlungen wird.

Der Ärger endet nicht dort aber. Ich ursprünglich wollte vorschlagen, eine gute bewährte Lösung der Anwendung „extra“ Parameter Event-Handler übergeben. In diesem Fall würde dies ermöglichen es Ihnen, den Index zu finden, ohne Gleichen oder die Name Zeichenfolge verwendet Es handelt sich im Grunde ein Wrapper-Delegierten zu schaffen, dass „gibt vor,“ ein ButtonPressEventHandler zu sein, aber intern übergibt ein int Ihre Begleitband Methode:

    Func<uint, ButtonPressEventHandler> indexWrapper = ((index) => ((s, e) => { AddButtonPressed_wrapped(s, e, index); }));   

    ...

    plus[i].ButtonPressEvent += indexWrapper(i);

    ...

    protected virtual void AddButtonPressed_wrapped(object sender, EventArgs e, uint index)
    {
      Console.WriteLine("Button pressed");
      Console.WriteLine("Index = {0}", index);
    }

Es kompiliert und läuft ohne Fehler, aber es hat das gleiche Problem, das Ereignis nie ausgelöst. Ich erkennen, dass Sie nicht ein Attribut direkt auf einem Delegaten / Lambda setzen. Also auch wenn der Träger Methode der Delegierte hat [GLib.ConnectBefore] nicht der Fall, so ist es nicht.

Als abschließende Bemerkung, könnten Sie das Klickereignis wie in dieses API Beispiel . Ich überprüfte, dass es wie erwartet funktioniert. Man würde denken, dass es nur auf Mausklicks feuern würde, aber es funktioniert tatsächlich Feuer auf Leer auch.

Andere Tipps

for (uint i = 0; i < 10; i++) 
{
    plus[i] = new Button();
    plus[i].Data.Add("Index",i);
    plus[i].ButtonPressEvent += AddButtonPressed;
    Add(plus[i]);
}

Handler:

protected virtual void AddButtonPressed(object sender, System.EventArgs e) {
   Console.WriteLine("Button pressed");
   Gtk.Button button = sender as Gtk.Button;
   Console.WriteLine("Index: {0}", button.Data["Index"]);
}

Ich bin ziemlich sicher, dass Sie tatsächlich benötigen, um die Tasten, um die GTK Fenster Hierarchie hinzufügen, so etwas wie:

    for (uint i = 0; i < 10; i++) {
        plus[i] = new Button();
        plus[i].Name = i.ToString();
        plus[i].ButtonPressEvent += AddButtonPressed;
        Add(plus[i]);
    }

Sollte die ähnlich sein, nie wirklich GTK verwendet <. <

Verwenden Tag-Eigenschaft, wenn Gtk-Taste hat eine.

for (uint i = 0; i < 10; i++) {
    plus[i] = new Button();
    plus[i].Name = i.ToString();
    plus[i].ButtonPressEvent += AddButtonPressed;
    plus[i].Tag = i;
    Add(plus[i]);
}

Handler:

protected virtual void AddButtonPressed(object sender, System.EventArgs e) {
   Console.WriteLine("Button pressed");
   Gtk.Button button = sender as Gtk.Button;
   Console.WriteLine("Index: {0}", button.Tag);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top