Autor |
Beitrag |
Sneedlewoods
      
Beiträge: 20
|
Verfasst: Do 11.04.13 02:02
Hallo,
1. ich habe eine Form1 erstellt
2. ich habe KeyPreview auf true gestellt
3. ich setze einen Button auf die Form
nun ist das Problem:
1. dass der Button immer den Focus hat
2. CanSelect der Form schreibgeschützt ist und auf false steht
3. CanFocus/CanSelect vom Button schreibgeschützt ist und true ist
Ich möchte gerne, dass der Button gar nicht erst den Fokus erhält, oder dass ich in der Lage bin, der Form den Focus zu geben. Denn sonst müsste ich wohl alle Button-aktivierenden Tasten beim Button abfangen? Der Button soll gar nicht erst über die Tastatur aktiviert werden, was ich wohl noch hinkriegen würde. Lieber wäre mir jedoch die Kontrolle über den Focus.
Ich habe nun schon etwas länger gesucht, und wundere mich, dass es dafür nicht eine einfache Lösung gibt.
Grüße Sneedle
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Do 11.04.13 10:42
Button ableiten, CanFocus oder CanSelect (je nachdem was du genau vor hast) überschreiben und false zurückgeben lassen.
Für einen sinnvollen Ratschlag sollten wir aber erstmal wissen warum du das willst was du da willst.
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Do 11.04.13 11:03
Als Quick&Dirty-Lösung würde mir einfallen, den Button durch ein Panel zu ersetzen. Sieht dann zwar evtl. etwas anders aus und entspricht nicht dem normalen Windows-Verhalten, aber ich denke mal, dass du das sowieso umgehen willst.
Ich denk da so an einen Klick-Wettbewerb, den man nicht durch drücken der Enter-Taste umgehen soll. Liege ich da in etwa richtig? 
_________________ We are, we were and will not be.
|
|
Sneedlewoods 
      
Beiträge: 20
|
Verfasst: Do 11.04.13 13:23
Danke für die Tips.
@Ralf das mit dem Button ableiten hab ich auch überlegt und versucht. Mein Problem dabei ist, dass er CanFocus nicht erkennt:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| public class myButton : Button { public override bool CanFocus ... public myButton() { this.CanFocus = false; } } |
Ansonsten muss man eben nicht wissen, warum ich das will. Das Problem ist da und sucht nach Lösungen, egal warum ich das will.
@Gausi
Ein anderes Control zu nehmen habe ich auch schon überlegt. Würde ich im Notfall vielleicht machen, aber schön find ich das nicht. Ich verstehe nicht, wieso es überhaupt so schwierig sein muss -.-
Nein das ist kein Klick-Wettbewerb  Aber das Problem ist das Gleiche. Ich fange Tastatureingaben auf Form1-Ebene ab. Wenn jedoch der Button den Focus hat, wird er aktiviert sobald man Leertaste oder Enter oder sowas drückt, was schlicht und einfach nicht immer sinnvoll ist.
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Do 11.04.13 14:39
CanFocus und CanSelect sind nicht virtual  Tja da war mein Vorschlag dann nicht wirklich hilfreich.
Vielleicht hilft es wenn du im Constructor des abgeleiteten Buttons den Style passend setzt.
C#-Quelltext 1:
| this.SetStyle(ControlStyles.Selectable, false); |
|
|
Sneedlewoods 
      
Beiträge: 20
|
Verfasst: Fr 12.04.13 01:21
Hallo also beim Button funktioniert das so nicht. Eventuell müsste ich das Panel ableiten und SetStyles ändern, aber dass würde bedeuten dass ich alle Labels, Buttons etc. selber in das Panel setzen muss, oder kann ich den Designer irgendwo dafür einspannen? Theoretisch müsste das ja gehen, ist das gleiche Objekt.
Mir gefällt allerdings gerade die Idee besser, die Tastatureingaben für den Button zu sperren. Dann muss ich die ganzen Elemente nicht erneut auf die Form setzen. Aber wie ich es mir dachte funktioniert leider auch nicht -.-
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| Button.KeyPress += new KeyPressEventHandler(this.ButtonNoKey); Button.KeyUp += new KeyEventHandler(this.ButtonNoKey);
private void ButtonNoKey(object sender, KeyPressEventArgs e) { e.Handled=true; } private void ButtonNoKey(object sender, KeyEventArgs e) { e.Handled=true; } |
Das hat leider nicht zum Erfolg geführt. Geht das irgendwie anders?
|
|
Sneedlewoods 
      
Beiträge: 20
|
Verfasst: Fr 12.04.13 01:31
OMG, auf meiner endlosen Suche nach einer Lösung, habe ich in einem anderen Forum einen beiläufigen Satz gefunden, der den Focus eines normalen Buttons verhindert!
C#-Quelltext
Ich probier mir hier nen Wolf  Leute es geht meistens einfach! :p
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 12.04.13 11:00
Das ist das Problem mit den Fragen stellen aber nicht die Details mitgeben wollen
Du hast gefragt wie man das focusieren verhindert zumindest ist das was hier angekommen ist. Deine Lösung ist jetzt aber den Button aus der Tabulatorreihenfolge zu nehmen. Wenn das reicht ok aber den Button per Keyboard focusieren und ausführen geht so natürlich immer noch. Man kann ja zum Beispiel per Cursortasten zum Button navigieren.
|
|
Sneedlewoods 
      
Beiträge: 20
|
Verfasst: Sa 13.04.13 12:37
Wir können ja jetzt noch lange darüber diskutieren, was aber zu nichts führen wird.
1. Letztendlich habe ich das Problem oben beschrieben, dass der Button immer den Focus hat. Dieses Problem wurde nun umgangen.
2. Die Cursor-Tasten führen nicht zu einer Aktivierung/Fokussierung!
3. In meinem 2. Post @Gausi sollte der unspektakuläre Hintergrund ersichtlich sein.
4. Mir ist bewusst dass es immer die Vertreter gibt, möglichst viel wissen zu müssen, weil sie dann eventuell auf bestimmte Ideen kommen. Diese Lösung kann man durchaus auch ohne viel Hintergrundwissen finden. (Zusätzlich siehe Punkt 3)
5. Ich hatte auch gesagt, die Tastatur für den Button komplett abzuschalten. Folglich brauche ich kein TabStop.
So hoffe, dass wir die Diskussion nun beenden können.
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Sa 13.04.13 13:05
OK dann keine Diskussion.
Dann nur eine Antwort zu dokumentarischen Zwecken für andere Leser.
TabStop verhindert nur das focussieren eines Controls über die Tabfolge es verhindert nicht das focussieren über andere Wege. In diesem speziellen Fall hier wo noch andere Dinge passieren mag das helfen im allgemeinen Fall wird das setzen von TabStop allein nicht helfen.
|
|
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Sa 13.04.13 14:06
Sneedlewoods hat folgendes geschrieben : |
2. ich habe KeyPreview auf true gestellt
|
hi, geht es dir darum, dass du die "tasten" nicht mehr angefangen kriegst, weil der Focus auf dem button ist?
wenn ja dann fang die "Tasten" doch mit
Delphi-Quelltext 1: 2: 3:
| GetAsyncKeystate( Taste )) |
Hier eine Liste der Taste:
www.delphipraxis.net...ruck-simulieren.html
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Sneedlewoods 
      
Beiträge: 20
|
Verfasst: Sa 13.04.13 21:00
Hi Ihope,
doch Tasten bekomme ich immernoch abgefangen. KeyPreview bewirkt ja eben, dass die Tasten zuerst zu den Form-Events geleitet wird und danach erst zu den Controls. Allerdings wird der Button eben immer ausgelöst wenn ich Return, Leertaste, etc. drücke, was nicht erwünscht ist, weil er den Focus hat, was ebenfalls nicht erwünscht ist.
Aber wie schon erwähnt, funktioniert es in diesem Falle mit TabStop=false. Ich habe nicht viel rumprobiert, aber bisher konnte keine Taste den Focus auf den Button legen.
Also alles i.O. 
|
|
Sneedlewoods 
      
Beiträge: 20
|
Verfasst: Sa 13.04.13 21:21
Also Ralf hatte Recht. Sobald ich mit der Maus den Button anklicke, hat er den Focus wieder. Mit den Tasten habe ich nachwievor keine Probleme.
Also bleibt die Suche nach einer Sicheren Methode offen.
|
|
Th69
      

Beiträge: 4796
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: So 14.04.13 12:17
Hallo,
hast du denn die von Ralf Jansen vorgeschlagene Möglichkeit
C#-Quelltext 1: 2: 3: 4: 5: 6: 7:
| public class NonFocusButton : Button { public NonFocusButton() { SetStyle(ControlStyles.Selectable, false); } } |
mal ausprobiert?
Anstatt abzuleiten, kannst du auch per Reflection diese Methode auf das Control (Button) anwenden:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| void SetControlNonSelectable(Control control) { Type type = control.GetType(); BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance; MethodInfo method = type.GetMethod( "SetStyle", flags ); if(method != null) { object[] param = { ControlStyles.Selectable, false }; method.Invoke(control, param); } } |
|
|
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: So 14.04.13 13:44
Um es zu lösen:
- Tabstop des Buttons auf FALSE setzen
UND die OnClick Procedure sollte so aussehen (am Beispiel von Button1)
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TForm1.Button1Click(Sender: TObject); begin Button1.Visible := False; Button1.Visible := True; end; |
allgemein also:
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TForm1.ClickButton(Sender: TObject); begin (Sender as TButton).Visible := False; (Sender as TButton).Visible := True; end; |
Edit: Es ist zwar in Delphi geschrieben, aber ich denke du verstehst damit was gemeint ist
-> Ein unsichtbares Object kann kein Focus haben ! somit verschwindet dieser bei Visisble := false;
damit der button aber weiterhin angezeigt wird wieder Visible := True;
... manche Compiler erkenen die "Sinnlosigkeit" und compilieren das deshalb gar nicht mit.. deshalb (falls das der Fall sein sollte) einfach mal ein delay(10) dazwischensetzen
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: So 14.04.13 14:14
Im NonFocusButton Code von TH69 sicherheitshalber noch im Konstruktor den Basisklassen Konstruktor aufrufen.
|
|
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: So 14.04.13 14:21
@Ralf Jansen:
Danke dass du TH69-Variante noch verbesserst  Aber ich denke meine "Art" ist leichter umzusetzen/zu verstehen oder?
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: So 14.04.13 15:12
@IhopeonlyReader: Ich vermute mal das das hier, in C#/Winforms mit vermutlich nur diesem Buttom auf der Form, nicht funktioniert.
Verstehe auch nicht wie das in Delphi helfen sollte? Wenn der Button den Focus bekommt wird kein Click ausgeführt. Warum sollte das rumschrauben an der Visibility in Click dann irgendwas ändern. Wenn du dafür sorgen willst das das der Button nach dem Click den Focus verliert, warum auch immer, sollte das einfacher gehen.
|
|
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: So 14.04.13 15:21
weil er nur durch die Maus den Focus bekommen kann..
aber du hast recht, man kann natürlcih auch mit der maus den Focus setzten OHNE das onClick ergeignis auszuführen.
deshalb verbessert:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| procedure TForm1.IrgendeinButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if (Button=mbLeft) then (Sender as TButton).OnClick(Sender); Button1.Visible := False; Button1.Visible := True; end; |
Edit: In Delphi funktioniert dieser Code um einem Button den "Focus" wegzunehmen, in C# nicht wie ich gerade festgestellt habe...
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Zuletzt bearbeitet von IhopeonlyReader am So 14.04.13 15:45, insgesamt 1-mal bearbeitet
|
|
Th69
      

Beiträge: 4796
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: So 14.04.13 15:43
Hallo Ralf,
der Default-Basisklassenkonstruktor wird in .NET automatisch beim Ableiten aufgerufen.
Nur wenn man einen Basisklassenkonstruktor mit Parametern aufrufen möchte/muß, dann muß man diesen explizit aufrufen.
|
|