Laden...

WPF: Focus für OnPreviewKeyDown/KeyBindings im UserControl

Erstellt von p!lle vor 7 Jahren Letzter Beitrag vor 7 Jahren 3.938 Views
p!lle Themenstarter:in
1.040 Beiträge seit 2007
vor 7 Jahren
WPF: Focus für OnPreviewKeyDown/KeyBindings im UserControl

Moin,

ich möchte in einem UserControl OnPreviewKeyDown überschreiben bzw. einfache KeyBindings nutzen. Leider funktioniert dies nicht in allen Fällen.

Wie bei Microsoft (Focus Overview) zu lesen ist, gibt es einen logischen und einen Tastaturfokus.

Das erklärt, warum es funktioniert, wenn "auswählbare" Elemente (wie TextBox, Button, CheckBox, ComboBox) auf dem UC selektiert werden, und warum es nicht funktioniert, wenn "nicht auswählbare" Elemente (wie GroupBox, Label) auf dem UC "selektiert" werden oder wenn an eine leere Stelle im UC geklickt wird.

Es gibt u.a. den Workaround, Focusable im UC auf true zu setzen und im Loaded bzw. MouseUp-Event über Keyboard.Focus das UC auszuwählen. Das finde ich jedoch unschön.

Hat zufällig jemand schon mal das gleiche Problem gehabt und eine elegantere Lösung?

3.170 Beiträge seit 2006
vor 7 Jahren

Hallo,

das geht wenn ich es richtig verstehe in die Richtung [gelöst] UserControl KeyDown aktivieren?

Kannst Dir ja mal den dort verlinkten Thread auf Stackoverflow anschauen. Es läuft allerdings auch dort darauf hinaus, das Focusable auf true gesetzt wird, also letztlich Dein bereits gefundener Workaround.
Eine andere Lösung wüsste ich jetzt auch nicht.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

P
157 Beiträge seit 2014
vor 7 Jahren

Hallo,

wofür brauchst du das denn ? ... du kannst das ganze auch wesentlich eleganter lösen, je nach anwendungsfall hast du verschiedene möglichkeiten.

grundsätzlich sind der logische fokus und tastaturfokus was ganz anderes, das eine ist wirklich für benutzereingaben gedacht, am logischen fokus hängt wesentlich mehr, als einfache eingaben...

du kannst mit behaviours arbeiten, bietet sich in manchen fällen an...wenn du einfach nur auf tastendruck innerhalb eines controls arbeiten willst, kannst du auch commandbindings verwenden...(bubbling/tunneling), je nach dem wie komplex dein ui-aufbau ist.

events zu abonnieren ist immer etwas "risky" ... events sind, wenn man nicht damit aufpasst, sehr schwer zu debuggen, da man mit denen ganz leicht einen zirkulären aufruf erzeugen kann, für die man wiederrum einen hack braucht um sie zu umgehen.

Wenn's zum weinen nicht reicht, lach drüber!

p!lle Themenstarter:in
1.040 Beiträge seit 2007
vor 7 Jahren

Danke für eure Antworten.

Ich habe es aktuell so gelöst, dass ich beim Loaded des Controls das KeyBinding zum ParentWindow hinzufüge - und beim Unloaded wieder entferne. Funktioniert ganz gut.

@Parso:
Ich benötige es, um auf eine Tastenkombination zu reagieren. 😁

P
157 Beiträge seit 2014
vor 7 Jahren

Dann reicht ein einfaches CommandBinding voll aus..deine Tastaturkombi wird, wenn es vom fokusierten Control nicht ausgewertet wird, an das Parent geschickt...bis es entweder beim Fenster ankommt oder auf einen "auswerter" trifft...

Geht also auch ohne "häggerei" im Code-Behind

vg

Wenn's zum weinen nicht reicht, lach drüber!

p!lle Themenstarter:in
1.040 Beiträge seit 2007
vor 7 Jahren

Mir ist ehrlich gesagt nicht ganz klar, worauf du hinaus willst. Wo wird denn jetzt das CommandBinding definiert? Hast du zufällig ein Beispiel?

P
157 Beiträge seit 2014
vor 7 Jahren

Du kannst über die InputBindings Tastenkombinationen mit einem Command verbinden, das Command kann zb in einer statischen Klasse oder deinem ViewModel hinterlegt sein:

    <Grid>
        <Grid.InputBindings>
            <KeyBinding Command="{x:Static MyCommandCollection.MyCommand}" Key="A" Modifiers="Control" ></KeyBinding>
        </Grid.InputBindings>
    </Grid>

CommandBinding war daher nicht ganz korrekt...ist immer ne Sache was man meint und was man sagt, bzw schreibt 😉

Wenn's zum weinen nicht reicht, lach drüber!

p!lle Themenstarter:in
1.040 Beiträge seit 2007
vor 7 Jahren

Genau das funktioniert eben nicht. Siehe Ausgangsbeitrag. 😉

P
157 Beiträge seit 2014
vor 7 Jahren

Hm habs mal Probiert...scheinbar "spruckt" das Bubbling drauf wenns an nem Panel hängt, sobald man das auf ein überliegendes Control legt, klappts wieder. Könntest rein theoretisch auf nen Container gehen...also ContentPresenter oder so, hab ich noch nicht probiert...müsste aber gehen...

Wenn's zum weinen nicht reicht, lach drüber!