Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Scrollbar-Schrittweite


aim65 - Sa 31.03.07 10:32
Titel: Scrollbar-Schrittweite
Hallo,

Habe hier folgendes Problem, von dem ich nicht weiß, ob es überhaupt eine Lösung gibt.
Suche hat nichts ergeben.

Scrollbar mit min=0, max=160000, LargeChange =100, SmallChange=1.

Geht alles soweit - ABER, wenn ich den Scrollbutton mit der Maus verschiebe, ergeben sich "krumme" Schrittweiten (hier 1431, unstabil +-1). Habe in ScrollChange probiert, die Schrittweite auf den glatten Wert von 2000 zu fixieren. Ging auch im Prinzip - nach Radio Eriwan - aber dann funktionierten Large- und SmallChange nicht mehr.

Kennt jemand einen Trick, mit der Maus+Scrollbutton glatte Schrittweiten zu erreichen und trotzdem LC & SC mit 100 bzw. 1 beizubehalten?

Gruß Horst


Lannes - Sa 31.03.07 17:30

Hallo,

wie wäre es mit runden:

Delphi-Quelltext
1:
i := Round(ScrollBar1.Position/100)*100;                    


aim65 - Sa 31.03.07 18:46

Hallo Lannes,

so ähnlich habe ich's schon probiert, das löst leider das Problem nicht. Die Schritte werden zwar mit Deinem Ansatz in Mehrfachen von Hundert ausgeführt, aber dann geht wieder SmallChange (=1) nicht mehr. :cry:
Offensichtlich gibt es keinen Weg, zwischen dem Klicken in die Scrollbarfelder und dem Verschieben des Buttons zu unterscheiden. So etwas wie eine MouseMove-Property fehlt ja leider. Die Drag-Optionen gehen überhaupt nicht für diese Sache.
Ich bin dankbar für jeden Ansatz, der zu einer Lösung führt. :flehan:
MfG, Horst


Lannes - Sa 31.03.07 21:48

Hallo,

wie soll denn reagiert werden?

z.B.
a) 6 > 106
oder
b) 6 > 100

Der Code arbeitet entsprechent Variante b):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  with ScrollBar do
    begin
    if Abs(Position - Tag) <> 1 then
      begin
      Tag := Round(Position/100)*100;
      Position := Tag;
      end
      else
        Tag := Position;
    Memo1.Lines.Add(IntToStr(Tag));
    end;


aim65 - So 01.04.07 09:29

Hallo,
hab's eben erst gesehen. Muss jetzt leider weg - aber das werde ich mal heute abend ausprobieren.
Ideal wäre natürlich Variante a). Es handelt sich um eine Frequenzeinstellung, wobei idealerweise die Abstufung 1000kHz (Button verschieben), 100khz (in Fläche klicken) und 1kHz (auf Pfeile klicken) wäre - ohne dass die jeweils "niederen" Stellen (100kHz bzw. 1kHz beeinflusst werden). Aber man könnte u.U. tolerieren, dass nur die Variante b) möglich ist, wenn es zu einer Lösung führt. Bis dann.

Danke, Horst


aim65 - Mo 02.04.07 09:42

Hallo Lannes,

hab's mal ausprobiert. Leider ergibt das seltsame Ergebnisse, wenn man dann versucht, mit den 1er-Schritten zu arbeiten. Auch die Änderung von "<>1" zu ">1" ergab nix Gescheites. Das ganze Problem ist m.E., dass man nicht unterscheiden kann, ob der Schieberegler bewegt oder in ein Feld geklickt wurde. Ich habs auch mit "OnStartDrag" usw. versucht, aber da weiß ich ehrlich gesagt auch nicht, wie diese Ereinisse in diesem Zusammenhang verwendet werden können. Die Hilfe (D3) ist da für mich nicht besonders hilfreich.
Ich glaube mittlerweile, dass es da keine vernünftige Lösung zu geben scheint.

Danke, Horst


Lannes - Mo 02.04.07 19:42

Hallo,
user profile iconaim65 hat folgendes geschrieben:
...
Das ganze Problem ist m.E., dass man nicht unterscheiden kann, ob der Schieberegler bewegt oder in ein Feld geklickt wurde.
...
in OnChange (bei Max 160000) kannst Du es feststellen durch den Vergleich der alten mit der neuen Position. Wenn die Differenz größer 100 ist, dann wird/ist die Positionsmarke gezogen worden.

Das Ereignis OnScroll bietet Dir über die Variable ScrollCode auch die benötigten Informationen.

die imho hilfreiche D3-Hilfe hat folgendes geschrieben:


Quelltext
1:
scPosition    Der Benutzer hat die Positionmarke bewegt und die Maustaste losgelassen.                    


Quelltext
1:
scTrack       Der Benutzer bewegt soeben die Positionsmarke.                    



aim65 - Di 03.04.07 09:22

Danke für den Tip. Werde mal weiterbasteln.
MfG Horst


aim65 - Di 03.04.07 13:24

Na, wer sagt's denn... Geht ja doch. :dance: :dance2:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode;
  var ScrollPos: Integer);
begin
  with ScrollBar1 do
    begin
      if   (ScrollCode = scTrack) or (Scrollcode = scPosition)
      then  ScrollPos := Trunc(ScrollPos / 1000) * 1000;
      AEdit1.Text := IntToStr(ScrollPos);
    end;
end;

Problem gelöst, danke Lannes.
Jetzt muss ich nur noch ein bisschen herumbasteln, damit der Wert der 100er + 1er erhalten bleibt und nicht auf Null gesetzt wird. Ist aber nicht soo wichtig.

MfG Horst