PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Windows Forms - Trackbar und das Ende des Scrollens


Sephiroth
2008-07-21, 23:50:12
Hi


Ich habe eine Trackbar mit vielen Teilschritten (100) und ich möchte eine Aktion erst dann ausführen, wenn der Benutzer die Trackbar nicht mehr bewegt, also fertig ist mit scrollen. Der Benutzer soll damit quasi erst den Wert auswählen können, ohne das währenddessen schon die Auswirkungen folgen, was bei 100-Teilschritten zu oft und zu schnell hintereinander geschehen würde.

Leider gibt es nur den Scroll-Event, den ich aber jetzt in ScrollStart und ScrollEnd aufteilen möchte/müsste.

Meine bisherige Idee sie so aus:

Scroll-Event setzt Flag das gescrollt wird und startet Timer1 mit einem gewissen Delay (sagen wir 400 ms)
Timer1 setzt Flag zurück und startet Timer2
Timer2 prüft, ob Flag nicht gesetzt ist und führt dann die eigentliche Arbeit aus; sonst beendet er sich sofort

Wenn der Benutzer fertig ist mit Scrollen, wird das Flag nicht erneut gesetzt, kein Timer1 gestartet und der zuletzt gestartete Timer2 weiß das der benutzer fertig ist mit scrollen und kann seine Arbeit verrichten.
Schlüssig?

Ich bin mit GUIs generell und den spezifischen Eigenschaften von C# (z.B. Delegates) nicht sonderlich vertraut, drum verzeiht mein naives vorgehen. :redface:

Wie kann ich es anders/besser machen?


p.s.
Ich könnte notfalls sicher auch die MouseUp und KeyUp Events nehmen ...

Gast
2008-07-21, 23:57:29
....


p.s.
Ich könnte notfalls sicher auch die MouseUp und KeyUp Events nehmen ...

Ebend, solang das Tracking vom Mouse-Event abhängig ist, erübrigt sich deine Frage eigentlich, oder?! ;)

Sephiroth
2008-07-22, 00:23:40
Ebend, solang das Tracking vom Mouse-Event abhängig ist, erübrigt sich deine Frage eigentlich, oder?! ;)
Ich möchte es trotzdem wissen. :D

Zählt das Mausrad auch zu MouseUp/MouseDown?

ScottManDeath
2008-07-22, 01:05:47
Gibts da nicht ein Validated event?

RattuS
2008-07-22, 01:34:55
Zählt das Mausrad auch zu MouseUp/MouseDown?
AFAIK nein. MouseUp/Down wird nur durch die 5 Standard-Maustasten ausgelöst. Man kann das aber sicherlich irgendwie hooken.

Die Mouse/Key Ups sind für dein Vorhaben aber auf jeden Fall zu bevorzugen. C# bietet im Gegensatz zu VB wenigstens auch den Scroll-Event an.

Edit: Das Validate dürfte nicht viel helfen, denn das bezieht sich nur auf den WM_PAINT-Event.

Sephiroth
2008-07-22, 01:36:06
Gibts da nicht ein Validated event?
Damit der Event ausgelöst wird, müsste der Benutzer aber den Fokus erst auf ein anderes Element setzen.

MouseCaptureChanged (http://msdn.microsoft.com/de-de/library/system.windows.forms.control.mousecapturechanged.aspx) kommt dem gesuchten schon recht nahe, greift aber nur wenn man die normalen Maustasten verwendet. Das Mausrad bleibt unbeachtet.

Der_Donnervogel
2008-07-22, 02:01:16
Man könnte den Scroll-Event auch mit nur einem Timer verwenden. Beim ersten Scroll-Event wird der Timer gestartet und falls der Timer schon läuft bei jedem weiteren Event wieder resettet. Wenn der Timer dann abgelaufen ist weiß man dass das Scrollen geendet hat, da ja ansonsten der Timer zurückgesetzt worden wäre.

Gast
2008-07-22, 02:27:46
Ach du lieber Himmel...

Bau da nochn MouseEvent ein und gut is (MSDN Beispiel):

using System;
using System.Drawing;
using System.Windows.Forms;

public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TrackBar trackBar1;
private System.Windows.Forms.TextBox textBox1;

[STAThread]
static void Main()
{
Application.Run(new Form1());
}

public Form1()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.trackBar1 = new System.Windows.Forms.TrackBar();

// TextBox for TrackBar.Value update.
this.textBox1.Location = new System.Drawing.Point(240, 16);
this.textBox1.Size = new System.Drawing.Size(48, 20);

// Set up how the form should be displayed and add the controls to the form.
this.ClientSize = new System.Drawing.Size(296, 62);
this.Controls.AddRange(new System.Windows.Forms.Control[] { this.textBox1, this.trackBar1 });
this.Text = "TrackBar Example";

// Set up the TrackBar.
this.trackBar1.Location = new System.Drawing.Point(8, 8);
this.trackBar1.Size = new System.Drawing.Size(224, 45);
this.trackBar1.Scroll += new System.EventHandler(this.trackBar1_Scroll);

// The Maximum property sets the value of the track bar when
// the slider is all the way to the right.
trackBar1.Maximum = 100;

// The TickFrequency property establishes how many positions
// are between each tick-mark.
trackBar1.TickFrequency = 1;

// The LargeChange property sets how many positions to move
// if the bar is clicked on either side of the slider.
trackBar1.LargeChange = 3;

// The SmallChange property sets how many positions to move
// if the keyboard arrows are used to move the slider.
trackBar1.SmallChange = 2;
}


private void trackBar1_Scroll(object sender, System.EventArgs e)
{
// Display the trackbar value in the text box.
textBox1.Text = "" + trackBar1.Value;
}
}

Gast
2008-07-22, 15:46:50
Ach du lieber Himmel...

Bau da nochn MouseEvent ein und gut is (MSDN Beispiel):

using System;
using System.Drawing;
using System.Windows.Forms;

public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TrackBar trackBar1;
private System.Windows.Forms.TextBox textBox1;

[STAThread]
static void Main()
{
Application.Run(new Form1());
}

public Form1()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.trackBar1 = new System.Windows.Forms.TrackBar();

// TextBox for TrackBar.Value update.
this.textBox1.Location = new System.Drawing.Point(240, 16);
this.textBox1.Size = new System.Drawing.Size(48, 20);

// Set up how the form should be displayed and add the controls to the form.
this.ClientSize = new System.Drawing.Size(296, 62);
this.Controls.AddRange(new System.Windows.Forms.Control[] { this.textBox1, this.trackBar1 });
this.Text = "TrackBar Example";

// Set up the TrackBar.
this.trackBar1.Location = new System.Drawing.Point(8, 8);
this.trackBar1.Size = new System.Drawing.Size(224, 45);
this.trackBar1.Scroll += new System.EventHandler(this.trackBar1_Scroll);

// The Maximum property sets the value of the track bar when
// the slider is all the way to the right.
trackBar1.Maximum = 100;

// The TickFrequency property establishes how many positions
// are between each tick-mark.
trackBar1.TickFrequency = 1;

// The LargeChange property sets how many positions to move
// if the bar is clicked on either side of the slider.
trackBar1.LargeChange = 3;

// The SmallChange property sets how many positions to move
// if the keyboard arrows are used to move the slider.
trackBar1.SmallChange = 2;
}


private void trackBar1_Scroll(object sender, System.EventArgs e)
{
// Display the trackbar value in the text box.
textBox1.Text = "" + trackBar1.Value;
}
}


Lies nochmal den ersten Beitrag, dann wirst du feststellen, dass der Scroll-Event unlängst genutzt wird.

Sephiroth
2008-07-24, 23:09:09
Man könnte den Scroll-Event auch mit nur einem Timer verwenden. Beim ersten Scroll-Event wird der Timer gestartet und falls der Timer schon läuft bei jedem weiteren Event wieder resettet. Wenn der Timer dann abgelaufen ist weiß man dass das Scrollen geendet hat, da ja ansonsten der Timer zurückgesetzt worden wäre.
Da tritt das Problem auf, dass unter gewissen Umständen der Timer nur bei ungerader Anzahl an Scroll-Events etwas tut.

1. Scroll-Event startet Timer mit x ms
2. Scroll-Event nach x-ε ms stoppt den Timer, bevor er etwas tut

Folge: keine Aktion wird ausgeführt, da Timer nicht mehr aktiv

ethrandil
2008-07-26, 01:29:47
Wie wärs mit:

ScrollEvent startet den Timer, wenn er noch nicht gestartet ist
ScrollEvent resettet den Timer, wenn er schon läuft
Wenn der Timer abläuft, löst du dein EndEvent aus (das ist immer genau die Laufzeit des Timers nach dem letzten ScrollEvent)

- eth

RattuS
2008-07-26, 02:08:06
Was spricht denn gegen den MouseUp-Event der Trackbar? Zieh einfach dann .Value raus und führ deine Funktion w/e aus.