2 votes

Mettre le focus sur un autre contrôle lorsqu'une touche est pressée sans code-behind

Je suis en train de mettre en place quelque chose comme un contrôle de l'autosuggestion : J'ai un contrôle utilisateur qui contient un TextBox et un ListBox . Lorsque l'utilisateur saisit du texte, je le traite avec System.Windows.Interactivity les comportements et le remplissage des ListBox avec quelques valeurs...

Tout fonctionne bien, mais je veux permettre à l'utilisateur de sélectionner des éléments dans la rubrique ListBox (c'est-à-dire de définir Focus sur le ListBox ) lorsque l'on appuie sur la touche de déplacement vers le bas.

Je sais qu'il est possible de gérer les KeyPressDown de l'événement TextBox dans le fichier .cs du code-behind, mais comment éviter cela ?

5voto

H.B. Points 76352

Si vous utilisez déjà Interactivity, cela ne devrait pas poser de problème. TriggerAction qui a les propriétés suivantes Key & TargetName pour déterminer quand et sur quoi se concentrer. Le placer dans un EventTrigger para PreviewKeyDown .

Exemple de mise en œuvre et d'utilisation :

<TextBox>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="PreviewKeyDown">
            <t:KeyDownFocusAction Key="Down"
                                  Target="{Binding ElementName=lbx}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>
<ListBox Name="lbx" ItemsSource="{Binding Data}" />

class KeyDownFocusAction : TriggerAction<UIElement>
{
    public static readonly DependencyProperty KeyProperty =
        DependencyProperty.Register("Key", typeof(Key), typeof(KeyDownFocusAction));
    public Key Key
    {
        get { return (Key)GetValue(KeyProperty); }
        set { SetValue(KeyProperty, value); }
    }

    public static readonly DependencyProperty TargetProperty =
        DependencyProperty.Register("Target", typeof(UIElement), typeof(KeyDownFocusAction), new UIPropertyMetadata(null));
    public UIElement Target
    {
        get { return (UIElement)GetValue(TargetProperty); }
        set { SetValue(TargetProperty, value); }
    }

    protected override void Invoke(object parameter)
    {
        if (Keyboard.IsKeyDown(Key))
        {
            Target.Focus();
        }
    }
}

Testé et fonctionnel, à noter que KeyDown ne le fait pas car les touches fléchées sont interceptées et marquées comme étant gérées par la TextBox.

3voto

Rachel Points 49408

Je ne pense pas que vous puissiez l'éviter

Qu'y a-t-il de mal à capturer le KeyDown de la TextBox et s'il s'agit d'une touche de flèche vers le haut ou vers le bas, il suffit de déclencher l'événement ListBox.KeyDown dans le code qui suit ?

Je ne vois aucune raison de ne pas utiliser le code-behind dans MVVM si c'est pour fournir une fonctionnalité spécifique à la vue telle que le focus

0voto

Contango Points 7976

Cette réponse est basée sur celle de H.B. et ajoute la possibilité de vérifier si la touche Ctrl est enfoncée. Cela signifie qu'il peut gérer des combinaisons de touches telles que Ctrl-F pour rechercher.

XAML

<TextBox>
<i:Interaction.Triggers>
    <i:EventTrigger EventName="PreviewKeyDown">
        <t:KeyDownFocusAction Key="Down" Ctrl="True"
                              Target="{Binding ElementName=lbx}" />
    </i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<ListBox Name="lbx" ItemsSource="{Binding Data}" />

Espaces de noms

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

Voir aide à l'ajout System.Windows.Interactivity .

Propriété de dépendance

public class KeyDownFocusAction : TriggerAction<UIElement>
{
    public static readonly DependencyProperty KeyProperty =
        DependencyProperty.Register("Key", typeof(Key), typeof(KeyDownFocusAction));
    public Key Key
    {
        get { return (Key)GetValue(KeyProperty); }
        set { SetValue(KeyProperty, value); }
    }

    public static readonly DependencyProperty CtrlProperty =
        DependencyProperty.Register("Ctrl", typeof(bool), typeof(KeyDownFocusAction));
    public bool Ctrl
    {
        get { return (bool)GetValue(CtrlProperty); }
        set { SetValue(CtrlProperty, value); }
    }

    public static readonly DependencyProperty TargetProperty =
        DependencyProperty.Register("Target", typeof(UIElement), typeof(KeyDownFocusAction), new UIPropertyMetadata(null));
    public UIElement Target
    {
        get { return (UIElement)GetValue(TargetProperty); }
        set { SetValue(TargetProperty, value); }
    }

    protected override void Invoke(object parameter)
    {
        if (Keyboard.IsKeyDown(Key))
        {
            if (Ctrl == true)
            {
                if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
                {
                    Target.Focus();
                }
            }
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X