48 votes

WPF MVVM Focus Field on Load

J'ai une vue qui a un seul TextBox et un couple Button s en dessous. Lorsque la fenêtre se charge, je veux que TextBox de se concentrer.

Si je n'utilisais pas MVVM, je me contenterais d'appeler TextBox.Focus() dans l'événement Loaded. Cependant, mon ViewModel ne connaît pas ma vue, alors comment puis-je accomplir ceci sans mettre du code dans le code de ma vue ?

EDIT : Après avoir lu les réponses j'ai décidé de mettre ce code dans la vue xaml

<DockPanel FocusManager.FocusedElement="{Binding ElementName=MessageTextBox}">    
    <TextBox Name="MessageTextBox" Text="{Binding Message}"/>
</DockPanel>

S'il s'agissait d'autre chose que de la mise au point initiale de la page, je recommanderais probablement la réponse de Jon Galloway, car elle peut être contrôlée à partir du ViewModel.

50voto

Anderson Imes Points 18093

Si cela vous rassure (cela me rassure aussi), vous pouvez le faire en Xaml en utilisant une propriété attachée :

http://msdn.microsoft.com/en-us/library/system.Windows.input.focusmanager.focusedelement.aspx

Tout ce que vous pouvez faire en codebehind, vous pouvez le faire en Xaml si vous connaissez les astuces. Heureusement, vous n'avez pas eu à mettre en œuvre cette astuce - MS l'a fait pour vous.

14voto

Martin Harris Points 18057

Dans ce cas, je pense qu'il est bon de mettre le code dans la vue. Le fait de mettre le focus sur un contrôle affecte le comportement de l'interface utilisateur plutôt que la logique de l'application et relève donc de la responsabilité de la vue.

9voto

Jon Galloway Points 28243
  1. Disposez d'une propriété dans votre ViewModel qui indique quel est l'élément actuellement ciblé.
  2. Utilisez le FocusManager pour vous lier à cette propriété.

    < Fenêtre FocusManager.FocusedElement="{Binding ElementName=ViewModel.FocusedItem}"> < /Window>

Votre ViewModel est un traducteur qui existe uniquement pour fournir des informations à la vue. Vous pouvez donc ajouter à la VM toutes les informations dont la vue a besoin pour fonctionner.

8voto

maciejkow Points 4504

En fait, la mise au point n'est-elle pas une préoccupation de l'interface utilisateur ? MVVM consiste à séparer les préoccupations - ce qui appartient au modèle est dans le modèle, ce qui appartient à la vue est dans la vue, et ce qui lie le modèle et la vue ensemble est dans le ViewModel (ceci est bien sûr une description trop simplifiée).

Cela signifie que la logique de l'interface utilisateur reste dans la vue - TextBox.Focus() est, à mon avis, la façon appropriée de le faire.

4voto

Steven Robbins Points 18791

Je considère que le contrôle avec le focus est très "visuel seulement", donc je n'aurais aucun problème à ce qu'il soit dans le code derrière.

L'idée d'une VM est d'éloigner la logique de la vue et de fournir une version de votre modèle adaptée aux liaisons de données, à laquelle la vue peut se lier. Cela ne signifie pas nécessairement que tous devrait se trouver dans la VM, juste le code logique et tout ce qui n'est pas directement lié à l'interface utilisateur.

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