Laden...

window lifetime

Erstellt von legio vor 16 Jahren Letzter Beitrag vor 16 Jahren 2.070 Views
L
legio Themenstarter:in
10 Beiträge seit 2007
vor 16 Jahren
window lifetime

hey,

ich habe eine fensterlose tray application. Diese soll nun durch ein kleines Benachrichtigungsfenster erweitert werden. Die tray applikation besitzt einen Timer der im Hintergrund regelmäßig einen Zustand überprüft. Sollte sich dieser ändern soll ein kleines Benachrichtigungsfenster angezeigt werden.

Der Timer funktioniert. Das Fenster existiert auch schon. Das Fenster besitzt zwei methoden um das Fenster einfliegen und ausfliegen zu lassen (durch 'Änderung des Y Wertes - auch timer gesteuert).

Mein Problem ist.. wie kann ich sicherstellen dass das Fenster

  1. eingeflogen
  2. ein paar sekunden angezeigt,
  3. ausgeflogen und
  4. abschließend wieder zerstört wird?

Meine Idee dazu:
Ich definiere ein paar bool variablen die den zustand der anwendung beschreiben (einflug, ausflug, anzeigen). Und erstelle dann einen 3ten timer (timer 1+2 sind speziell für die animationen ein- und ausflug), der z.B. jede sekunde aufgerufen wird und je nach zustand und im falle von status:anzeigen einem counter bestimmt ob es zeit ist das fenster wieder zu schließen. Aber dann hab ich für meine mini tray anwendung 4 timer im einsatz.. übertreib ich da? Hab ichs voll vertimert? Oder würde man sowas so machen?

998 Beiträge seit 2007
vor 16 Jahren

    public partial class Form2 : Form
    {
        int xres = 1280;
        int yres = 1024;
        Timer tmr = new Timer();

        public Form2()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Läßte Fenster einfliegen
        /// </summary>
        public void einfliegen()
        {
            tmr.Interval = 30;                              // Zeit um die das Fenster um 5px verschoben wird
            this.Location.X = xres - this - width - 50;     // Fenster 50px vom rechten Rand darstellen
            this.Location.Y = y;                            // Y-Pos unterhalb des sichtbareb Bereichs
            tmr.Tick += new EventHandler(einTick);          // Ein-Tick ausführen wenn Timer abgelaufen ist
            tmr.Start();                                    // Timer starten
            this.Show();                                    // Fenster zeigen
        }

        // Wird aufgerufen wenn Fenster beim einfliegen verschoben werden soll
        void einTick(object sender, EventArgs e)
        {
            this.Location.Y -= 5;                           // Fenster um 5px ins Bild schieben
            if (this.Location.Y >= this.yres - this.Height) // Wenn Fenster an Endpunkt
            {   
                tmr.Stop();                                 // Timer stoppen
                tmr.Tick -= einTick;                        // Event löschen (geht das so!?!?)

                tmr.Interval = 5000;                        // Fenster wird 5 sek angezeigt
                tmr.Start();                                // TImer starten
                tmr.Tick += new EventHandler(ausfliegen);   // Nach 5 sek "ausfleigen" aufrufen
            }
        }

        // Wird aufgereufen wenn Fenster ausgeflogen werden soll
        void ausfliegen(object sender, EventArgs e)
        {
            tmr.Interval = 30;                              // Alle 30ms das Fenster um 5px verschieben
            tmr.Tick += new EventHandler(ausTick);          // ausTick aufrufen wenn Timer abgelaufen
            tmr.Start();                                    // Timer starten
        }

        // Wird aufgerufen wenn Fenster beim ausfliegen verschoben werden soll
        void ausTick(object sender, EventArgs e)
        {
            this.Location.Y += 5;                           // Um 5px aus dem Sichtbereich schieben
            if (this.Location.Y <= this.yres)               // Wenn Fenster aus sichtbereich
            {   
                tmr.Stop();                                 // tmr löschen
                tmr.Dispose();                              // res freimachen
                tmr = null;                                 // tmr nullen
                this.Hide();                                // fenster hiden
            }
        }
    }

Ist nun einfach mal so hingeschrieben wie ich es mir vorstellen würde... Für resx und resy war ich zu faul die Funktionen rauszusuchen 😜

Gelöschter Account
vor 16 Jahren

Tipp:

@legio
in David's beispiel wird von einer statischen bildschirmgröße ausgegangen

mit System.Windows.Forms.Screen.PrimaryScreen würde es bei jeder größe richtig sein

MfG janismac

L
legio Themenstarter:in
10 Beiträge seit 2007
vor 16 Jahren

wie gesagt, fenster + animation existieren schon, hab auch "Screen.PrimaryScreen" verwendet 🙂 Das MSN-Messenger-like Ding ist ziemlich riesig.. aber ich glaub der macht das so ähnlich wie ich mir das dachte.. aber ich bin noch nicht ganz durch.

Zu dem Beispiel von DavidT...
würde das funktionieren wenn ich einfliegen(); im konstruktor der klasse aufrufe? Ich denke schon. Ansonsten müsste ich die Funktionen von außerhalb, aus meinem tick event handlers meines omnipräsenten Timers heraus starten, wo das anzeigen des benachrichtungsfensters sowieso getriggered wird.

Quasi so:


void pulseTimer(object sender, EventArgs e) {
    pulseTimer.Stop();
    if (...) {
       NotificationWindow tmp = new NotificationWindow();
       tmp.Show(); // form laden
       tmp.einfliegen();  // einfliegen, anzeigen, ausfliegen
       tmp.Close(); // form zerstören, ressourcen freigeben
    }
    pulseTimer.Start();
}

was beide genannten Beispiele auf jeden Fall gemeinsam haben, sind die Timer. Also werde ich wohl auch Timer verwenden. Ich hatte mir da noch so wilde Szenarien überlegt mit Threads und so.. per konstruktur gleich mal einfliegen lassen, dann stehts erstmal im Raum. Und dann mit einem einfachen countdown (sowas muss es doch auch irgendwo geben) das Form_Closing event auslösen und dann dort den ausfliegen() code triggern..

P.S.:
ob

tmr.Tick -= einTick;                        // Event löschen (geht das so!?!?)

geht, weiss ich auch (noch) nicht.

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo legio,

Aber dann hab ich für meine mini tray anwendung 4 timer im einsatz.. übertreib ich da?

da Einfliegen Warten und Ausfliegen sequentiell und nicht gleichzeitig erfolgt, reicht hier auf jeden Fall ein Timer. Ich würde den EventHandler des Timers immer gleich lassen und anhand des Zustands entscheiden, was gerade zu tun ist.

tmr.Tick -= einTick;

Ja, das geht, würde ich aber hier wie gesagt nicht machen.

herbivore

998 Beiträge seit 2007
vor 16 Jahren

Hey Herbivore,

warum würdest du das nicht machen? Nur aus Gründen der Übersicht oder hat es auch Performancegründe?

Gruß David

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo DavidT,

weil es übersichtlicher, in meinen Augen logischer und im Allgemeinen auch sicherer ist

Zur Sicherheit:

Es besteht dann nicht die Gefahr, dass sich die Timer gegenseitig in die Quere kommen. Das tun sie zwar auch bei mehreren nicht, wenn man sauber programmiert, aber wenn man nur einen Timer hat, besteht die Gefahr erst gar nicht. 🙂

Zur Logik:

Es ist ein bisschen so wie in Brauche Rat: Wie in der GUI warten? . Wenn ich etwas sequentiell machen will, dann brauche ich nicht drei Threads, die ich dann mühsam synchronisiere, damit sie hintereinander laufen, sondern nehme einen. So ähnlich sehe ich es hier mit den Timern. Statt einen anzuhalten und den nächsten zu starten, nimmt man einfach nur einen und macht dort eben das, was gerade zu tun ist.

herbivore

998 Beiträge seit 2007
vor 16 Jahren

ich meinte das mit dem "-= einTick"

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo DavidT,

weil ich nur einen Timer nehmen würden mit einem festen EventHandler. Der EventHandler muss dann nur einmal registriert werden. Dieser EventHandler würde anhand des aktuellen Zustands entscheiden, was gerade zu tun ist.

Den EventHandler je nach aktuellem Zustand auszutauschen, halte ich für unübersichtlich und verwirrend.

herbivore