Mettre l'accent sur textbox dans le WPF à partir du modèle de vue (C#)

j'ai un TextBox et un Button à mon avis.

maintenant je vérifie une condition sur un clic de bouton et si la condition s'avère être fausse, l'affichage du message à l'utilisateur, et puis je dois régler le curseur à la commande TextBox .

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 modèle de vue.

Le CompanyAssociation est le nom de la vue.

mais le curseur ne se positionne pas dans le 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}"/>
113
demandé sur Massimiliano Kraus 2009-08-31 10:15:30

19 réponses

Permettez-moi de répondre à votre question en trois parties.

  1. je me demande ce qui est " cs.txtCompanyID" dans votre exemple? Est-il un contrôle de zone de texte? Si oui, alors vous êtes sur la mauvaise voie. En général, ce n'est pas une bonne idée d'avoir n'importe quelle référence à L'UI dans votre modèle de vue. Vous pouvez demander "Pourquoi?"mais c'est une autre question à poste sur Stackoverflow :).

  2. La meilleure façon de suivre les problèmes avec l'Accent être... débogage du code source .Net. Pas de blague. Il m'a sauvé beaucoup de temps à plusieurs reprises. Pour activer le débogage du code source. net, reportez-vous au blog de Shawn Bruke.

  3. enfin, l'approche générale que j'utilise pour mettre au point à partir de ViewModel est des propriétés attachées. J'ai écrit très simple propriété jointe, qui peut être mis sur n'importe quel UIElement. Et il peut être lié à la propriété de ViewModel "IsFocused" par exemple. Le voici:

    public static class FocusExtension
    {
        public static bool GetIsFocused(DependencyObject obj)
        {
            return (bool) obj.GetValue(IsFocusedProperty);
        }
    
        public static void SetIsFocused(DependencyObject obj, bool value)
        {
            obj.SetValue(IsFocusedProperty, value);
        }
    
        public static readonly DependencyProperty IsFocusedProperty =
            DependencyProperty.RegisterAttached(
                "IsFocused", typeof (bool), typeof (FocusExtension),
                new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
    
        private static void OnIsFocusedPropertyChanged(
            DependencyObject d, 
            DependencyPropertyChangedEventArgs e)
        {
            var uie = (UIElement) d;
            if ((bool) e.NewValue)
            {
                uie.Focus(); // Don't care about false values.
            }
        }
    }
    

    maintenant dans votre View (dans XAML) vous pouvez lier cette propriété à votre ViewModel:

    <TextBox local:FocusExtension.IsFocused="{Binding IsUserNameFocused}" />
    

Espérons que cela aide :). S'il ne se réfère pas à la réponse #2.

santé.

234
répondu Anvaka 2016-06-06 14:55:18

je sais que cette question a été répondue mille fois maintenant, mais j'ai fait quelques modifications à la contribution D'Anvaka qui je pense aidera d'autres qui ont eu des problèmes similaires que j'avais.

tout D'abord, j'ai changé la propriété ci-dessus attachée comme suit:

public static class FocusExtension
{
    public static readonly DependencyProperty IsFocusedProperty = 
        DependencyProperty.RegisterAttached("IsFocused", typeof(bool?), typeof(FocusExtension), new FrameworkPropertyMetadata(IsFocusedChanged){BindsTwoWayByDefault = true});

    public static bool? GetIsFocused(DependencyObject element)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }

        return (bool?)element.GetValue(IsFocusedProperty);
    }

    public static void SetIsFocused(DependencyObject element, bool? value)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }

        element.SetValue(IsFocusedProperty, value);
    }

    private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var fe = (FrameworkElement)d;

        if (e.OldValue == null)
        {
            fe.GotFocus += FrameworkElement_GotFocus;
            fe.LostFocus += FrameworkElement_LostFocus;
        }

        if (!fe.IsVisible)
        {
            fe.IsVisibleChanged += new DependencyPropertyChangedEventHandler(fe_IsVisibleChanged);
        }

        if ((bool)e.NewValue)
        {
            fe.Focus();
        }
    }

    private static void fe_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var fe = (FrameworkElement)sender;
        if (fe.IsVisible && (bool)((FrameworkElement)sender).GetValue(IsFocusedProperty))
        {
            fe.IsVisibleChanged -= fe_IsVisibleChanged;
            fe.Focus();
        }
    }

    private static void FrameworkElement_GotFocus(object sender, RoutedEventArgs e)
    {
        ((FrameworkElement)sender).SetValue(IsFocusedProperty, true);
    }

    private static void FrameworkElement_LostFocus(object sender, RoutedEventArgs e)
    {
        ((FrameworkElement)sender).SetValue(IsFocusedProperty, false);
    }
}

la raison pour laquelle j'ai ajouté les références de visibilité était les onglets. Apparemment, si vous avez utilisé la propriété attachée sur n'importe quel autre onglet à l'extérieur de l'onglet initialement visible, le la propriété n'a pas fonctionné jusqu'à ce que vous porté manuellement le contrôle.

l'autre obstacle était de créer une façon plus élégante de réinitialiser la propriété sous-jacente à false quand il a perdu la mise au point. C'est là que le foyer perdu événements sont arrivés.

<TextBox            
    Text="{Binding Description}"
    FocusExtension.IsFocused="{Binding IsFocused}"/>

S'il y a une meilleure façon de traiter la question de la visibilité, veuillez me le faire savoir.

Note: Merci à 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.

61
répondu Zamotic 2018-07-25 14:14:26

je pense que le meilleur moyen est de garder le principe MVVM propre, vous devez donc utiliser la classe Messenger fournie avec la lumière MVVM et voici comment l'utiliser:

dans votre modèle de vue(exampleViewModel.cs): écrire

 Messenger.Default.Send<string>("focus", "DoFocus");

maintenant à votre avis.cs(pas le code XAML de la vue.XAML.cs) écrire ce qui suit dans le constructeur

 public MyView()
        {
            InitializeComponent();

            Messenger.Default.Register<string>(this, "DoFocus", doFocus);
        }
        public void doFocus(string msg)
        {
            if (msg == "focus")
                this.txtcode.Focus();
        }

que la méthode owrks juste fine et avec moins de code et de maintenir MVVM standards

27
répondu Adam 2011-11-30 11:29:57

Aucune 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.

Utilisation serait comme suit:

<TextBox ... h:FocusBehavior.IsFocused="True"/>

et la mise en œuvre serait la suivante:

/// <summary>
/// Behavior allowing to put focus on element from the view model in a MVVM implementation.
/// </summary>
public static class FocusBehavior
{
    #region Dependency Properties
    /// <summary>
    /// <c>IsFocused</c> dependency property.
    /// </summary>
    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached("IsFocused", typeof(bool?),
            typeof(FocusBehavior), new FrameworkPropertyMetadata(IsFocusedChanged));
    /// <summary>
    /// Gets the <c>IsFocused</c> property value.
    /// </summary>
    /// <param name="element">The element.</param>
    /// <returns>Value of the <c>IsFocused</c> property or <c>null</c> if not set.</returns>
    public static bool? GetIsFocused(DependencyObject element)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }
        return (bool?)element.GetValue(IsFocusedProperty);
    }
    /// <summary>
    /// Sets the <c>IsFocused</c> property value.
    /// </summary>
    /// <param name="element">The element.</param>
    /// <param name="value">The value.</param>
    public static void SetIsFocused(DependencyObject element, bool? value)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }
        element.SetValue(IsFocusedProperty, value);
    }
    #endregion Dependency Properties

    #region Event Handlers
    /// <summary>
    /// Determines whether the value of the dependency property <c>IsFocused</c> has change.
    /// </summary>
    /// <param name="d">The dependency object.</param>
    /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
    private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Ensure it is a FrameworkElement instance.
        var fe = d as FrameworkElement;
        if (fe != null && e.OldValue == null && e.NewValue != null && (bool)e.NewValue)
        {
            // Attach to the Loaded event to set the focus there. If we do it here it will
            // be overridden by the view rendering the framework element.
            fe.Loaded += FrameworkElementLoaded;
        }
    }
    /// <summary>
    /// Sets the focus when the framework element is loaded and ready to receive input.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
    private static void FrameworkElementLoaded(object sender, RoutedEventArgs e)
    {
        // Ensure it is a FrameworkElement instance.
        var fe = sender as FrameworkElement;
        if (fe != null)
        {
            // Remove the event handler registration.
            fe.Loaded -= FrameworkElementLoaded;
            // Set the focus to the given framework element.
            fe.Focus();
            // Determine if it is a text box like element.
            var tb = fe as TextBoxBase;
            if (tb != null)
            {
                // Select all text to be ready for replacement.
                tb.SelectAll();
            }
        }
    }
    #endregion Event Handlers
}
15
répondu Leo Vildosola 2011-06-26 00:50:35

c'est un vieux fil, mais il ne semble pas y avoir de réponse avec du code qui traite les problèmes avec la réponse acceptée D'Anavanka: il ne fonctionne pas si vous définissez la propriété dans le viewmodel à false, ou si vous définissez votre propriété à true, l'utilisateur clique manuellement sur quelque chose d'autre, et puis vous le définissez à nouveau à true. La solution de Zamotic ne fonctionnait pas dans ces cas-là non plus.

la synthèse de certaines des discussions ci-dessus me donne le code ci-dessous qui ne traitent ces questions je pense:

public static class FocusExtension
{
    public static bool GetIsFocused(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsFocusedProperty);
    }

    public static void SetIsFocused(DependencyObject obj, bool value)
    {
        obj.SetValue(IsFocusedProperty, value);
    }

    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached(
         "IsFocused", typeof(bool), typeof(FocusExtension),
         new UIPropertyMetadata(false, null, OnCoerceValue));

    private static object OnCoerceValue(DependencyObject d, object baseValue)
    {
        if ((bool)baseValue)
            ((UIElement)d).Focus();
        else if (((UIElement) d).IsFocused)
            Keyboard.ClearFocus();
        return ((bool)baseValue);
    }
}

cela dit, c'est encore 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 façon, donc peut-être codebehind est la voie à suivre.

11
répondu Rich N 2015-07-10 11:02:42

dans mon cas, L'extension de Focus n'a pas fonctionné jusqu'à ce que je change la méthode OnIsFocusedPropertyChanged. L'original ne fonctionnait que dans debug quand un point d'arrêt a stoppé le processus. À l'exécution, le processus est trop rapide et rien ne se passe. Avec cette petite modification et à l'aide de notre ami Tâche, cela fonctionne bien dans les deux scénarios.

private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
  var uie = (UIElement)d;
  if ((bool)e.NewValue)
  {
    var action = new Action(() => uie.Dispatcher.BeginInvoke((Action)(() => uie.Focus())));
    Task.Factory.StartNew(action);
  }
}
4
répondu Vincent Rithner 2013-07-11 21:12:49

anvakas brilliant code est pour les applications Windows Desktop. Si vous êtes comme moi et que vous avez besoin de la même solution pour les applications Windows Store, ce code peut être pratique:

public static class FocusExtension
{
    public static bool GetIsFocused(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsFocusedProperty);
    }


    public static void SetIsFocused(DependencyObject obj, bool value)
    {
        obj.SetValue(IsFocusedProperty, value);
    }


    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached(
         "IsFocused", typeof(bool), typeof(FocusExtension),
         new PropertyMetadata(false, OnIsFocusedPropertyChanged));


    private static void OnIsFocusedPropertyChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
        {
            var uie = d as Windows.UI.Xaml.Controls.Control;

            if( uie != null )
            {
                uie.Focus(FocusState.Programmatic);
            }
        }
    }
}
3
répondu PEK 2014-02-02 09:46:39

le problème est qu'une fois que L'IsUserNameFocused est réglé à true, il ne sera jamais false. Cela résout cela en manipulant le GotFocus et LostFocus pour le Frameworkkelement.

j'avais des problèmes avec le formatage du code source alors voici un lien

2
répondu Shawn 2010-06-24 20:01:26

pour ceux qui essayaient d'utiliser la solution d'Anvaka ci-dessus, j'avais des problèmes avec la reliure qui ne fonctionnait que la première fois, car lostfocus ne mettrait pas à jour la propriété à false. Vous pouvez définir manuellement la propriété à false puis à true à chaque fois, mais une meilleure solution pourrait être de faire quelque chose comme ça dans votre propriété:

bool _isFocused = false;
    public bool IsFocused 
    {
        get { return _isFocused ; }
        set
        {
            _isFocused = false;
            _isFocused = value;
            base.OnPropertyChanged("IsFocused ");
        }
    }

de cette façon, vous avez seulement besoin de mettre à vrai, et il obtiendra la concentration.

1
répondu Tyrsius 2011-10-07 15:24:06

j'utilise WPF / Caliburn Micro a constaté que "dfaivre" a fait un général et solution viable ici: http://caliburnmicro.codeplex.com/discussions/222892

1
répondu kpp 2013-10-31 16:13:06

j'ai trouvé Crucial 's solution de la IsVisible problème très utile. Il 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 fait.

à la méthode modifiée Isfocused j'ai ajouté:

    if (!fe.IsEnabled)
    {
        fe.IsEnabledChanged += fe_IsEnabledChanged;
    }

et voici le handler:

private static void fe_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    var fe = (FrameworkElement)sender;
    if (fe.IsEnabled && (bool)((FrameworkElement)sender).GetValue(IsFocusedProperty))
    {
        fe.IsEnabledChanged -= fe_IsEnabledChanged;
        fe.Focus();
    }
}
0
répondu Wayne Maurer 2017-05-23 12:18:10

Pour Silverlight:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace MyProject.Behaviors
{
    public class FocusBehavior : Behavior<Control>
    {
        protected override void OnAttached()
        {
            this.AssociatedObject.Loaded += AssociatedObject_Loaded;
            base.OnAttached();
        }

        private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
        {
            this.AssociatedObject.Loaded -= AssociatedObject_Loaded;
            if (this.HasInitialFocus || this.IsFocused)
            {
                this.GotFocus();
            }
        }

        private void GotFocus()
        {
            this.AssociatedObject.Focus();
            if (this.IsSelectAll)
            {
                if (this.AssociatedObject is TextBox)
                {
                    (this.AssociatedObject as TextBox).SelectAll();
                }
                else if (this.AssociatedObject is PasswordBox)
                {
                    (this.AssociatedObject as PasswordBox).SelectAll();
                }
                else if (this.AssociatedObject is RichTextBox)
                {
                    (this.AssociatedObject as RichTextBox).SelectAll();
                }
            }
        }

        public static readonly DependencyProperty IsFocusedProperty =
            DependencyProperty.Register(
                "IsFocused",
                typeof(bool),
                typeof(FocusBehavior),
                new PropertyMetadata(false, 
                    (d, e) => 
                    {
                        if ((bool)e.NewValue)
                        {
                            ((FocusBehavior)d).GotFocus();
                        }
                    }));

        public bool IsFocused
        {
            get { return (bool)GetValue(IsFocusedProperty); }
            set { SetValue(IsFocusedProperty, value); }
        }

        public static readonly DependencyProperty HasInitialFocusProperty =
            DependencyProperty.Register(
                "HasInitialFocus",
                typeof(bool),
                typeof(FocusBehavior),
                new PropertyMetadata(false, null));

        public bool HasInitialFocus
        {
            get { return (bool)GetValue(HasInitialFocusProperty); }
            set { SetValue(HasInitialFocusProperty, value); }
        }

        public static readonly DependencyProperty IsSelectAllProperty =
            DependencyProperty.Register(
                "IsSelectAll",
                typeof(bool),
                typeof(FocusBehavior),
                new PropertyMetadata(false, null));

        public bool IsSelectAll
        {
            get { return (bool)GetValue(IsSelectAllProperty); }
            set { SetValue(IsSelectAllProperty, value); }
        }

    }
}

LoginViewModel.cs:

    public class LoginModel : ViewModelBase
    {
        ....

        private bool _EmailFocus = false;
        public bool EmailFocus
        {
            get
            {
                return _EmailFocus;
            }
            set
            {
                if (value)
                {
                    _EmailFocus = false;
                    RaisePropertyChanged("EmailFocus");
                }
                _EmailFocus = value;
                RaisePropertyChanged("EmailFocus");
            }
        }
       ...
   }

Login.xaml:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:beh="clr-namespace:MyProject.Behaviors"

<TextBox Text="{Binding Email, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    <i:Interaction.Behaviors>
        <beh:FocusBehavior IsFocused="{Binding EmailFocus}" IsSelectAll="True"/>
    </i:Interaction.Behaviors>
</TextBox>

ou

<TextBox Text="{Binding Email, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    <i:Interaction.Behaviors>
        <beh:FocusBehavior HasInitialFocus="True" IsSelectAll="True"/>
    </i:Interaction.Behaviors>
</TextBox>

pour définir la mise au point devrait simplement le faire en code:

EmailFocus = true;

N'oubliez pas que ce plugin fait partie d'une page html, donc d'autres contrôles dans la page Pourraient Avoir le focus

if (!Application.Current.IsRunningOutOfBrowser)
{
    System.Windows.Browser.HtmlPage.Plugin.Focus();
}
0
répondu ADM-IT 2013-11-29 11:29:47

, Vous pouvez utiliser le ViewCommand modèle de conception. Il décrit une méthode pour le modèle de conception MVVM pour contrôler une vue à partir d'un modèle de vue avec des commandes.

Je l'ai implémenté en me basant sur la suggestion du Roi A. Majid d'utiliser la classe MVVM Light Messenger. La classe ViewCommandManager gère les commandes d'invocation dans les vues connectées. C'est essentiellement l'autre direction des commandes régulières, pour ces cas où un ViewModel a besoin de faire une action dans son point de Vue. Il utilise la réflexion comme les commandes liées aux données et les références faibles pour éviter les fuites de mémoire.

http://dev.unclassified.de/source/viewcommand (également publié sur Codeprojet)

0
répondu ygoe 2014-02-01 11:59:59

j'ai trouvé la solution en éditant le code comme suit. Il n'est pas nécessaire de définir la propriété Binding D'abord False puis True.

public static class FocusExtension
{

    public static bool GetIsFocused(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsFocusedProperty);
    }


    public static void SetIsFocused(DependencyObject obj, bool value)
    {
        obj.SetValue(IsFocusedProperty, value);
    }


    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached(
         "IsFocused", typeof(bool), typeof(FocusExtension),
         new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));


    private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d != null && d is Control)
        {
            var _Control = d as Control;
            if ((bool)e.NewValue)
            {
                // To set false value to get focus on control. if we don't set value to False then we have to set all binding
                //property to first False then True to set focus on control.
                OnLostFocus(_Control, null);
                _Control.Focus(); // Don't care about false values.
            }
        }
    }

    private static void OnLostFocus(object sender, RoutedEventArgs e)
    {
        if (sender != null && sender is Control)
        {
            (sender as Control).SetValue(IsFocusedProperty, false);
        }
    }
}
0
répondu Bharat Mendapara 2014-12-11 12:33:38

personne ne semble avoir inclus l'étape finale pour faciliter la mise à jour des attributs via des variables liées. Voici ce que j'ai trouvé. Laissez-moi savoir si il ya une meilleure façon de le faire.

XAML

    <TextBox x:Name="txtLabel"
      Text="{Binding Label}"
      local:FocusExtension.IsFocused="{Binding txtLabel_IsFocused, Mode=TwoWay}" 
     />

    <Button x:Name="butEdit" Content="Edit"
        Height="40"  
        IsEnabled="{Binding butEdit_IsEnabled}"                        
        Command="{Binding cmdCapsuleEdit.Command}"                            
     />   

ViewModel

    public class LoginModel : ViewModelBase
    {

    public string txtLabel_IsFocused { get; set; }                 
    public string butEdit_IsEnabled { get; set; }                


    public void SetProperty(string PropertyName, string value)
    {
        System.Reflection.PropertyInfo propertyInfo = this.GetType().GetProperty(PropertyName);
        propertyInfo.SetValue(this, Convert.ChangeType(value, propertyInfo.PropertyType), null);
        OnPropertyChanged(PropertyName);
    }                


    private void Example_function(){

        SetProperty("butEdit_IsEnabled", "False");
        SetProperty("txtLabel_IsFocused", "True");        
    }

    }
0
répondu Hugh 2016-06-16 11:50:26

tout d'abord, je voudrais remercier Avanka pour m'aider à résoudre mon problème de mise au point. Il y a cependant un bug dans le code qu'il a posté, à savoir dans la ligne: si (E. OldValue = = null)

le problème que j'avais était que si vous cliquez d'abord dans votre vue et de concentrer 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 comme

public static class ExtensionFocus
    {
    static ExtensionFocus()
        {
        BoundElements = new List<string>();
        }

    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached("IsFocused", typeof(bool?),
        typeof(ExtensionFocus), new FrameworkPropertyMetadata(false, IsFocusedChanged));

    private static List<string> BoundElements;

    public static bool? GetIsFocused(DependencyObject element)
        {
        if (element == null)
            {
            throw new ArgumentNullException("ExtensionFocus GetIsFocused called with null element");
            }
        return (bool?)element.GetValue(IsFocusedProperty);
        }

    public static void SetIsFocused(DependencyObject element, bool? value)
        {
        if (element == null)
            {
            throw new ArgumentNullException("ExtensionFocus SetIsFocused called with null element");
            }
        element.SetValue(IsFocusedProperty, value);
        }

    private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        var fe = (FrameworkElement)d;

        // OLD LINE:
        // if (e.OldValue == null)
        // TWO NEW LINES:
        if (BoundElements.Contains(fe.Name) == false)
            {
            BoundElements.Add(fe.Name);
            fe.LostFocus += OnLostFocus;
            fe.GotFocus += OnGotFocus;
            }           


        if (!fe.IsVisible)
            {
            fe.IsVisibleChanged += new DependencyPropertyChangedEventHandler(fe_IsVisibleChanged);
            }

        if ((bool)e.NewValue)
            {
            fe.Focus();             
            }
        }

    private static void fe_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
        var fe = (FrameworkElement)sender;

        if (fe.IsVisible && (bool)((FrameworkElement)sender).GetValue(IsFocusedProperty))
            {
            fe.IsVisibleChanged -= fe_IsVisibleChanged;
            fe.Focus();
            }
        }

    private static void OnLostFocus(object sender, RoutedEventArgs e)
        {
        if (sender != null && sender is Control s)
            {
            s.SetValue(IsFocusedProperty, false);
            }
        }

    private static void OnGotFocus(object sender, RoutedEventArgs e)
        {
        if (sender != null && sender is Control s)
            {
            s.SetValue(IsFocusedProperty, true);
            }
        }
    }
0
répondu user2127475 2017-11-22 09:54:45

faites Simplement ceci:

<Window x:class...
   ...
   ...
   FocusManager.FocusedElement="{Binding ElementName=myTextBox}"
>
<Grid>
<TextBox Name="myTextBox"/>
...
0
répondu Zoltan 2018-07-06 11:31:21
public class DummyViewModel : ViewModelBase
    {
        private bool isfocused= false;
        public bool IsFocused
        {
            get
            {
                return isfocused;
            }
            set
            {
                isfocused= value;
                OnPropertyChanged("IsFocused");
            }
        }
    }
-1
répondu Jayasri 2015-03-23 06:55:05
System.Windows.Forms.Application.DoEvents();
Keyboard.Focus(tbxLastName);
-7
répondu KitWest 2011-11-09 17:58:05