WPF-MVVM: Définition du focus du contrôle de l’interface utilisateur à partir de ViewModel

Quelle est une bonne pratique pour définir le focus du contrôle dans l’architecture MVVM?

La façon dont je l’envisage est d’utiliser une propriété ViewModel qui déclencherait un changement de focus si nécessaire. Et que les contrôles d’interface utilisateur lient / écoutent cette propriété afin que, si elle change, le focus approprié soit défini.

Je le vois comme une chose ViewModel, parce que je veux définir le focus approprié après une certaine action effectuée par ViewModel, comme le chargement de certaines données.

Quelle est la meilleure pratique?

Utilisez la propriété attachée IsFocused comme suggéré dans la réponse ici: Définir le focus sur la zone de texte dans WPF à partir du modèle de vue (C #)

Ensuite, vous pouvez simplement lier une propriété dans votre modèle de vue.

Si vous utilisez Caliburn.Micro, voici un service que j’ai créé pour définir Focus sur n’importe quel contrôle de la vue héritée de Screen.

Remarque: Cela ne fonctionnera que si vous utilisez Caliburn.Micro pour votre framework MVVM.

public static class FocusManager { public static bool SetFocus(this IViewAware screen ,Expression> propertyExpression) { return SetFocus(screen ,propertyExpression.GetMemberInfo().Name); } public static bool SetFocus(this IViewAware screen ,ssortingng property) { Contract.Requires(property != null ,"Property cannot be null."); var view = screen.GetView() as UserControl; if ( view != null ) { var control = FindChild(view ,property); bool focus = control != null && control.Focus(); return focus; } return false; } private static FrameworkElement FindChild(UIElement parent ,ssortingng childName) { // Confirm parent and childName are valid. if ( parent == null || ssortingng.IsNullOrWhiteSpace(childName) ) return null; FrameworkElement foundChild = null; int childrenCount = VisualTreeHelper.GetChildrenCount(parent); for ( int i = 0; i < childrenCount; i++ ) { FrameworkElement child = VisualTreeHelper.GetChild(parent ,i) as FrameworkElement; if ( child != null ) { BindingExpression bindingExpression = GetBindingExpression(child); if ( child.Name == childName ) { foundChild = child; break; } if ( bindingExpression != null ) { if ( bindingExpression.ResolvedSourcePropertyName == childName ) { foundChild = child; break; } } foundChild = FindChild(child ,childName); if ( foundChild != null ) { if ( foundChild.Name == childName ) break; BindingExpression foundChildBindingExpression = GetBindingExpression(foundChild); if ( foundChildBindingExpression != null && foundChildBindingExpression.ResolvedSourcePropertyName == childName ) break; } } } return foundChild; } private static BindingExpression GetBindingExpression(FrameworkElement control) { if ( control == null ) return null; BindingExpression bindingExpression = null; var convention = ConventionManager.GetElementConvention(control.GetType()); if ( convention != null ) { var bindablePro = convention.GetBindableProperty(control); if ( bindablePro != null ) { bindingExpression = control.GetBindingExpression(bindablePro); } } return bindingExpression; } } 

Comment l'utiliser?

De votre ViewModel hérité de Caliburn.Micro.Screen ou Caliburn.Micro.ViewAware

this.SetFocus(()=>ViewModelProperty); ou this.SetFocus("Property");

Comment ça marche?

Cette méthode essaiera de rechercher un élément dans l'arborescence visuelle de la vue et le focus sera défini sur n'importe quel contrôle correspondant. Si aucun contrôle de ce type n'a été trouvé, il utilisera les conventions BindingConventions utilisées par Caliburn.Micro.

Pour ex.,

Il recherchera la propriété dans l'expression BindingExpression du contrôle. Pour TextBox, il vérifiera si cette propriété est liée à la propriété Text, le focus sera alors défini.

ViewModel lève un événement à la vue lui indiquant que l’action est terminée et que la vue définit le focus.

Vous pouvez introduire une interface pour la vue afin que ViewModel puisse indiquer à la vue de définir le focus. L’exemple d’application BookLibrary du framework d’application WPF (WAF Application Framework) montre comment procéder. Veuillez regarder le BookListViewModel.

La question a été posée à quelques resockets, malheureusement les réponses ne concernent que WPF. Donc, pour la lumière argentée en utilisant MVVM, vous pouvez également vous connecter avec n’importe quelle propriété pour plus de détails s’il vous plaît visitez le lien suivant

http://codenicely.blogspot.com/2012/01/how-to-set-textbox-focus-in-silverlight.html