J'ai un TextBox
et un Button
à mon avis.
Maintenant, je vérifie une condition lors d'un clic sur le bouton et si la condition s'avère être fausse, j'affiche le message à l'utilisateur, puis je dois placer le curseur sur le TextBox
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.
Le CompanyAssociation
est le nom de la vue.
Mais le curseur n'est pas défini dans le fichier TextBox
.
Le 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}"/>
Réponses:
Permettez-moi de répondre à votre question en trois parties.
Je me demande ce qu'est "cs.txtCompanyID" dans votre exemple? S'agit-il d'un contrôle TextBox? Si oui, alors vous êtes sur la mauvaise voie. De manière générale, ce n'est pas une bonne idée d'avoir une référence à l'interface utilisateur dans votre ViewModel. Vous pouvez demander "Pourquoi?" mais c'est une autre question à publier sur Stackoverflow :).
La meilleure façon de dépister les problèmes avec Focus est ... de déboguer le code source .Net. Sans blague. Cela m'a fait gagner beaucoup de temps à plusieurs reprises. Pour activer le débogage du code source .net, consultez le blog de Shawn Bruke .
Enfin, l'approche générale que j'utilise pour définir le focus à partir de ViewModel est les propriétés attachées. J'ai écrit une propriété jointe très simple, qui peut être définie sur n'importe quel UIElement. Et il peut être lié à la propriété "IsFocused" de ViewModel par exemple. C'est ici:
Maintenant, dans votre View (en XAML), vous pouvez lier cette propriété à votre ViewModel:
J'espère que cela t'aides :). Si cela ne fait pas référence à la réponse n ° 2.
À votre santé.
la source
Keyboard.Focus(uie);
depuis votreOnIsFocusedPropertyChanged
événement si vous souhaitez que votre contrôle reçoive le focus clavier ainsi que le focus logique...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, je dois même réinitialiser le 'IsFocused' sur false dans le ViewModel, si je veux définir le focus plusieurs fois. Mais alors cela fonctionne, là où certaines 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 reçu une réponse mille fois maintenant, mais j'ai apporté quelques modifications à la contribution d'Anvaka qui, je pense, aideront d'autres personnes qui ont eu des problèmes similaires.
Tout d'abord, j'ai changé la propriété attachée ci-dessus comme suit:
Ma raison d'ajouter les références de visibilité était les onglets. Apparemment, si vous utilisiez la propriété jointe sur un autre onglet en dehors de l'onglet initialement visible, la propriété jointe ne fonctionnait pas tant que vous ne mettiez pas en évidence manuellement le contrôle.
L'autre obstacle était de créer une manière plus élégante de réinitialiser la propriété sous-jacente à false lorsqu'elle perdait le focus. C'est là que les événements de perte de concentration sont intervenus.
S'il existe une meilleure façon de gérer le problème de visibilité, veuillez me le faire savoir.
Remarque: Merci à Apfelkuacha pour la suggestion de placer le BindsTwoWayByDefault dans DependencyProperty. Je l'avais fait il y a longtemps dans mon propre code, mais je n'ai jamais mis à jour ce message. Le Mode = TwoWay n'est plus nécessaire dans le code WPF en raison de ce changement.
la source
fe.Dispatcher.BeginInvoke(new Action(() => { fe.Focus(); }), DispatcherPriority.Loaded);
qu'il est mis à jour après son chargement. Plus d'informations ici: telerik.com/forums/isfocused-property#OXgFYZFOg0WZ2rxidln61QJe pense que le meilleur moyen est de garder le principe MVVM propre, donc en gros, vous devez utiliser la classe Messenger fournie avec le MVVM Light et voici comment l'utiliser:
dans votre viewmodel (exampleViewModel.cs): écrivez ce qui suit
maintenant dans votre View.cs (pas le XAML le view.xaml.cs) écrivez ce qui suit dans le constructeur
cette méthode fonctionne très bien et avec moins de code et en maintenant les normes MVVM
la source
Aucun de ceux-ci n'a fonctionné pour moi exactement, mais pour le bénéfice des autres, c'est ce que j'ai fini par écrire en me basant sur une partie du code déjà fourni ici.
L'utilisation serait la suivante:
Et la mise en œuvre serait la suivante:
la source
Ceci est un ancien fil de discussion, mais il ne semble pas y avoir de réponse avec un code qui résout les problèmes avec la réponse acceptée d'Anavanka: cela ne fonctionne pas si vous définissez la propriété dans le modèle de vue sur false, ou si vous définissez votre propriété sur true, l'utilisateur clique manuellement sur autre chose, puis vous le redéfinissez sur true. Je n'ai pas non plus réussi à faire fonctionner la solution de Zamotic de manière fiable dans ces cas.
Rassembler certaines des discussions ci-dessus me donne le code ci-dessous qui résout ces problèmes, je pense:
Cela dit, cela reste complexe pour quelque chose qui peut être fait en une seule ligne dans codebehind, et CoerceValue n'est pas vraiment destiné à être utilisé de cette manière, alors peut-être que codebehind est la voie à suivre.
la source
Dans mon cas, FocusExtension n'a pas fonctionné jusqu'à ce que je change la méthode OnIsFocusedPropertyChanged. L'original ne fonctionnait qu'en débogage lorsqu'un point d'arrêt a arrêté le processus. Au moment de l'exécution, le processus est trop rapide et rien ne s'est passé. Avec cette petite modification et l'aide de notre ami Task, cela fonctionne bien dans les deux scénarios.
la source
Le problème est qu'une fois que IsUserNameFocused est défini sur true, il ne sera jamais faux. Cela résout le problème en gérant GotFocus et LostFocus pour FrameworkElement.
J'avais des problèmes avec le formatage du code source alors voici un lien
la source
Le code brillant d'Anvakas est destiné aux applications Windows Desktop. Si vous êtes comme moi et que vous avez besoin de la même solution pour les applications du Windows Store, ce code peut être utile:
la source
Pour ceux qui essayaient d'utiliser la solution d'Anvaka ci-dessus, j'avais des problèmes avec la liaison ne fonctionnant que la première fois, car lostfocus ne mettrait pas à jour la propriété sur false. Vous pouvez définir manuellement la propriété sur false, puis sur true à chaque fois, mais une meilleure solution pourrait être de faire quelque chose comme ceci dans votre propriété:
De cette façon, vous n'aurez besoin que de le définir sur true, et il obtiendra le focus.
la source
J'utilise WPF / Caliburn Micro a constaté que "dfaivre" a fait une solution générale et réalisable ici: http://caliburnmicro.codeplex.com/discussions/222892
la source
J'ai trouvé une solution en éditant le code comme suit. Il n'est pas nécessaire de définir d'abord la propriété Binding sur False puis sur True.
la source
Pour Silverlight:
LoginViewModel.cs:
Login.xaml:
OU
Pour définir le focus, faites-le simplement dans le code:
N'oubliez pas que ce plugin fait partie d'une page html, donc d'autres contrôles de la page peuvent avoir le focus
la source
Vous pouvez utiliser le modèle de conception ViewCommand . Il décrit une méthode permettant au modèle de conception MVVM de contrôler une vue à partir d'un ViewModel avec des commandes.
Je l'ai implémenté sur la base de la suggestion de King A.Majid d'utiliser la classe MVVM Light Messenger. La classe ViewCommandManager gère l'appel de commandes dans les vues connectées. C'est fondamentalement l'autre direction des commandes régulières, pour ces cas où un ViewModel doit effectuer une action dans sa vue. Il utilise la réflexion comme les commandes liées aux données et les WeakReferences pour éviter les fuites de mémoire.
http://dev.unclassified.de/source/viewcommand (également publié sur CodeProject)
la source
Personne ne semble avoir inclus la dernière étape pour faciliter la mise à jour des attributs via des variables liées. Voici ce que j'ai trouvé. Faites-moi savoir s'il existe une meilleure façon de procéder.
XAML
VoirModèle
la source
Tout d'abord, je voudrais remercier Avanka de m'avoir aidé à résoudre mon problème de concentration. Il y a cependant un bug dans le code qu'il a posté, à savoir dans la ligne: if (e.OldValue == null)
Le problème que j'ai eu était que si vous cliquez d'abord dans votre vue et que vous concentrez le contrôle, e.oldValue n'est plus nulle. Ensuite, lorsque vous définissez la variable pour focaliser le contrôle pour la première fois, les gestionnaires lostfocus et gotfocus ne sont pas définis. Ma solution à cela était la suivante:
la source
Faites juste ceci:
la source
Après avoir implémenté la réponse acceptée, j'ai rencontré un problème selon lequel lors de la navigation dans les vues avec Prism, la zone de texte ne recevait toujours pas le focus. Une modification mineure du gestionnaire PropertyChanged l'a résolu
la source
Une approche alternative basée sur la réponse @Sheridan ici
Dans votre modèle de vue, configurez votre liaison de la manière habituelle, puis définissez SomeTextIsFocused sur true pour définir le focus sur votre zone de texte
la source
J'ai trouvé Crucial la solution « au problème IsVisible très utile. Cela n'a pas complètement résolu mon problème, mais un code supplémentaire suivant le même modèle pour le modèle IsEnabled l'a fait.
À la méthode IsFocusedChanged, j'ai ajouté:
Et voici le gestionnaire:
la source
la source
la source