Définir le focus sur la zone de texte dans WPF de la vue modèle
J'ai un TextBox
et un Button
de mon point de vue.
Maintenant, je suis à la vérification d'une condition clic de bouton et si la condition se révèle être faux, affichant le message à l'utilisateur, et alors je dois mettre le curseur sur le TextBox
de contrôle.
if (companyref == null)
{
var cs = new Lipper.Nelson.AdminClient.Main.Views.ContactPanels.CompanyAssociation();
MessageBox.Show("Company does not exist.", "Error", MessageBoxButton.OK,
MessageBoxImage.Exclamation);
cs.txtCompanyID.Focusable = true;
System.Windows.Input.Keyboard.Focus(cs.txtCompanyID);
}
Le code ci-dessus est dans le ViewModel.
La CompanyAssociation
est le nom de la vue.
Mais le curseur n'est pas configuré dans le TextBox
.
Le code xaml est:
<igEditors:XamTextEditor Name="txtCompanyID"
KeyDown="xamTextEditorAllowOnlyNumeric_KeyDown"
ValueChanged="txtCompanyID_ValueChanged"
Text="{Binding Company.CompanyId,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
Width="{Binding ActualWidth, ElementName=border}"
Grid.Column="1" Grid.Row="0"
VerticalAlignment="Top"
HorizontalAlignment="Stretch"
Margin="0,5,0,0"
IsEnabled="{Binding Path=IsEditable}"/>
<Button Template="{StaticResource buttonTemp1}"
Command="{Binding ContactCommand}"
CommandParameter="searchCompany"
Content="Search"
Width="80"
Grid.Row="0" Grid.Column="2"
VerticalAlignment="Top"
Margin="0"
HorizontalAlignment="Left"
IsEnabled="{Binding Path=IsEditable}"/>
- Lorsque vous êtes à l'aide de caliburn.micro ceci c'est une excellente solution.
Vous devez vous connecter pour publier un commentaire.
Permettez-moi de répondre à votre question en trois parties.
Je me demandais qu'est-ce que "cs.txtCompanyID" dans votre exemple? Est-il un contrôle de zone de texte? Si oui, alors vous êtes sur la mauvaise voie. Généralement parlant, il n'est pas une bonne idée d'avoir toute référence à une INTERFACE utilisateur dans votre ViewModel. Vous pouvez demander "Pourquoi?", mais c'est une autre question à poste sur Stackoverflow :).
La meilleure façon de suivre les problèmes avec l'Accent, c'est... le débogage .Net code source. Pas de blague. Il m'a sauvé beaucoup de temps à plusieurs reprises. Pour l'activer .net code source de débogage reportez-vous à Shawn Bruke de l' blog.
Enfin, l'approche générale que j'utilise pour définir le focus à partir de ViewModel est Attaché Propriétés. J'ai écrit très simple attaché à la propriété, qui peut être fixé sur n'importe quel UIElement. Et il peut être lié à la propriété du ViewModel "IsFocused" par exemple. Ici, il est:
Maintenant dans votre Vue (XAML) vous pouvez lier cette propriété à votre ViewModel:
Espère que cela aide :). Si elle ne fait pas référence à la réponse #2.
Acclamations.
Keyboard.Focus(uie);
de votreOnIsFocusedPropertyChanged
cas si vous voulez que votre contrôle pour recevoir le Focus du Clavier ainsi que le Focus Logiqueobj.SetValue(IsFocusedProperty, value);
àobj.SetValue(IsFocusedProperty, false);
et ne pas avoir à définir de faux et c'est encore vrai....if ((bool)e.NewValue && uie.Dispatcher != null) { uie.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => uie.Focus())); // invoke behaves nicer, if e.g. you have some additional handler attached to 'GotFocus' of UIE. uie.SetValue(IsFocusedProperty, false); // reset bound value if possible, to allow setting again ...
Parfois j'ai même réinitialiser le "IsFocused' à false dans le ViewModel, si je veux mettre l'accent à plusieurs reprises. Mais il fonctionne, où d'autres méthodes ont échoué.public bool IsFocused { get { return _isFocused; } set { if (_isFocused == value) { _isFocused = false; OnPropertyChanged(); } _isFocused = value; OnPropertyChanged(); } }
Je sais que cette question a été répondu mille fois plus maintenant, mais j'ai fait quelques modifications pour Anvaka contribution qui je pense va aider d'autres personnes qui avaient le même problème que j'avais.
Tout d'abord, j'ai changé le au-dessus de la Propriété Attachée de la sorte:
Ma raison de l'ajout de la visibilité des références ont été onglets. Apparemment, si vous avez utilisé la propriété attachée sur un autre onglet en dehors de la initialement visible de l'onglet, la propriété attachée à ne pas travailler jusqu'à ce que vous porté manuellement le contrôle.
L'autre obstacle était de créer un moyen plus élégant de la réinitialisation de la propriété sous-jacente à false quand il a perdu le focus. C'est là que le foyer perdu événements sont arrivés.
Si il y a une meilleure façon de gérer la visibilité de la question, s'il vous plaît laissez-moi savoir.
Note: Grâce à Apfelkuacha pour la suggestion de mettre le BindsTwoWayByDefault dans le DependencyProperty. J'avais fait cela il y a longtemps dans mon propre code, mais jamais mis à jour ce post. Le Mode=TwoWay n'est plus nécessaire dans le code WPF en raison de ce changement.
fe.Dispatcher.BeginInvoke(new Action(() => { fe.Focus(); }), DispatcherPriority.Loaded);
qu'il est mis à jour après il est chargé. Plus d'infos ici: telerik.com/forums/isfocused-property#OXgFYZFOg0WZ2rxidln61Qif (e.NewValue != null && (bool)e.NewValue)
et maintenant fonctionne bienJe pense que la meilleure façon est de garder le MVVM principe propre,
donc, fondamentalement, vous devez utiliser la Classe Messenger fourni avec le MVVM Light et voici comment l'utiliser:
dans votre viewmodel(exampleViewModel.cs):écrire la suite de
maintenant dans votre point de Vue.cs(pas le code XAML de la vue.xaml.cs) écrire le code suivant dans le constructeur
que la méthode owrks très bien et avec moins de code et le maintien de MVVM normes
Aucun de ces fonctionné pour moi, mais pour le bénéfice des autres, c'est ce que j'ai fini par écrire basé sur le code déjà fourni ici.
D'utilisation serait comme suit:
Et la mise en œuvre serait comme suit:
C'est un vieux thread, mais il ne semble pas être une réponse avec un code qui résout les problèmes avec Anavanka est accepté réponse: il ne fonctionne pas si vous définissez la propriété du viewmodel pour de faux, ou si vous définissez votre propriété à true, l'utilisateur manuellement clique sur quelque chose d'autre, et puis vous attribuez la valeur true à nouveau. Je ne pouvais pas obtenir Zamotic de solution à fonctionner de manière fiable dans ces affaires.
Rassemblant certaines des discussions ci-dessus me donne le code ci-dessous qui répond à ces questions, je pense:
Cela dit, c'est toujours complexe pour quelque chose qui peut être fait en une ligne dans le code-behind, et CoerceValue n'est pas vraiment destiné à être utilisé de cette façon, peut-être que le code-behind est le chemin à parcourir.
Dans mon cas, le FocusExtension n'a pas fonctionné jusqu'à ce que je change la méthode OnIsFocusedPropertyChanged. L'original a été de travailler uniquement dans le débogage lors d'un point de rupture arrêté le processus. Au moment de l'exécution, le processus est trop rapide et rien ne s'est vraiment passé. Avec cette petite modification et à l'aide de notre ami Tâche, cela fonctionne bien dans les deux scénarios.
Anvakas brillant code pour les applications de Bureau Windows. Si vous êtes comme moi et ont besoin de la même solution pour les applications du Windows Store ce code pourrait être à portée de main:
Le problème est qu'une fois le IsUserNameFocused est défini sur true, il ne sera jamais faux. Cela résout par la manipulation de la GotFocus et LostFocus FrameworkElement.
J'ai eu du mal avec la source de formatage de code voici donc une lien
Pour ceux qui essaient d'utiliser Anvaka la solution ci-dessus, j'ai eu des problèmes avec la liaison seul à travailler la première fois, comme lostfocus ne serait pas de mise à jour de la valeur false à la propriété. Vous pouvez définir manuellement la valeur false à la propriété et donc vrai à chaque fois, mais une meilleure solution pourrait être de faire quelque chose comme ceci dans votre propriété:
De cette façon, vous ne jamais avoir besoin de l'activer, et il sera en obtenir le focus.
- Je utiliser WPF /Caliburn Micro a constaté que "dfaivre" a fait un général et solution viable
ici:
http://caliburnmicro.codeplex.com/discussions/222892
J'ai trouvé la solution en modifiant le code par la suite. Il n'est pas nécessaire pour définir la propriété de Liaison de la première de Faux que de Vrais.
Pour Silverlight:
LoginViewModel.cs:
De connexion.xaml:
OU
Pour définir le focus doit juste le faire dans le code:
Oubliez pas que ce plugin est une partie d'une page html, de sorte que d'autres contrôles dans la page peut avoir le focus
Vous pouvez utiliser le ViewCommand modèle de conception. Il décrit une méthode pour le design pattern MVVM de contrôle de la Vue à partir d'un ViewModel avec les commandes.
J'ai mis en place sur la base Roi A. Majid la suggestion d'utiliser le MVVM Light classe Messenger. Le ViewCommandManager classe gère la en invoquant commandes connecté vues. En gros, c'est l'autre sens de régulièrement des Commandes, pour ces cas, lorsqu'un ViewModel besoin de faire un peu d'action dans sa Vue. Il utilise la réflexion comme liée à des données de commandes et de WeakReferences pour éviter les fuites de mémoire.
http://dev.unclassified.de/source/viewcommand (également publié sur CodeProject)
Tout d'abord je tiens à remercier Avanka pour m'aider à résoudre mon problème de focus. Il y a cependant un bug dans le code, il a affiché, à savoir dans la ligne:
si (e.OldValue == null)
Le problème que j'avais était que si vous cliquez d'abord dans votre point de vue et de se concentrer le contrôle, l'e.oldValue n'est plus nulle. Ensuite, lorsque vous définissez la variable de concentrer le contrôle pour la première fois, cette résultats dans la perte focus et gotfocus gestionnaires de ne pas être ensemble.
Ma solution à ce problème est comme suit:
Après la mise en œuvre de la accepté de répondre je n'ai couru à travers un problème lors de la navigation dans les vues avec le Prisme de la zone de texte ne serait toujours pas obtenir le focus. Un changement mineur à la PropertyChanged gestionnaire résolu
Une approche alternative fondée sur @Sheridan réponse ici
Dans votre modèle d'affichage configurer votre liaison dans la façon habituelle, puis définissez la SomeTextIsFocused à true pour définir le focus sur la zone de texte
J'ai trouvé Crucial's solution de la IsVisible problème très utile. Il n'a pas complètement résoudre mon problème, mais certains code supplémentaire suivant le même schéma pour la IsEnabled modèle n'.
À la IsFocusedChanged méthode que j'ai ajouté:
Et voici le gestionnaire de:
Personne ne semble avoir compris l'étape finale pour le rendre facile pour mettre à jour les attributs via lié variables. Voici ce que j'ai trouvé. Laissez-moi savoir si il ya une meilleure façon de le faire.
XAML
ViewModel
Viens de le faire: