web-dev-qa-db-fra.com

Définir le focus sur la zone de texte dans WPF à partir du modèle d'affichage (C #)

J'ai une TextBox et une Button à mon avis.

Maintenant, je vérifie une condition au clic du bouton et, si la condition s'avère être fausse, affiche le message à l'utilisateur, puis je dois placer le curseur sur le contrôle 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 ViewModel.

La CompanyAssociation est le nom de la vue.

Mais le curseur ne se met pas dans la 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}"/>
117
priyanka.sarkar

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

  1. Je me demande quelle est "cs.txtCompanyID" dans votre exemple? Est-ce un contrôle TextBox? Si oui, alors vous êtes dans le mauvais sens. De manière générale, il n'est pas judicieux de faire référence à l'interface utilisateur dans votre ViewModel. Vous pouvez demander "Pourquoi?" mais ceci est une autre question à poster sur Stackoverflow :).

  2. Le meilleur moyen 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. Pour activer le débogage du code source .net, référez-vous à de Shawn Bruke blog.

  3. Enfin, l’approche générale que j’utilise pour définir le focus de ViewModel est Propriétés attachées. J'ai écrit une propriété attachée très simple, qui peut être définie sur n'importe quel UIElement. Et il peut être lié à la propriété de ViewModel "IsFocused" par exemple. C'est ici:

    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 vue (en XAML), vous pouvez lier cette propriété à votre ViewModel:

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

J'espère que cela t'aides :). Si cela ne se réfère pas à la réponse # 2. 

À votre santé.

239
Anvaka

Je sais que cette question a déjà été répondue mille fois, mais j’ai apporté quelques modifications à la contribution d’Anvaka qui, je pense, aideront les autres qui ont des problèmes similaires à ceux que j’avais.

Tout d'abord, j'ai changé la propriété attachée ci-dessus 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 des onglets. Apparemment, si vous utilisiez la propriété attachée sur un autre onglet en dehors de l'onglet initialement visible, la propriété attachée ne fonctionnait pas tant que vous n'aviez pas focalisé le contrôle manuellement.

L’autre obstacle consistait à créer un moyen plus élégant de remettre à zéro la propriété sous-jacente lorsqu’elle perdait la concentration. C'est là que les événements de focus perdu sont entrés.

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

S'il y a une meilleure façon de traiter le problème de visibilité, s'il vous plaît faites le moi savoir.

Remarque: Merci à Apfelkuacha pour la suggestion de placer BindsTwoWayByDefault dans DependencyProperty. Je l'avais fait il y a longtemps dans mon propre code, mais je n'ai jamais mis à jour ce post. Le mode = TwoWay n'est plus nécessaire dans le code WPF en raison de cette modification.

64
Zamotic

Je pense que le meilleur moyen est de garder le principe de MVVM propre, Vous devez donc utiliser essentiellement la classe Messenger fournie avec MVVM Light. Voici comment l'utiliser:

dans votre viewmodel (exampleViewModel.cs): écrivez ce qui suit 

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

maintenant dans votre View.cs (pas le XAML le view.xaml.cs) écrivez 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();
        }

cette méthode owrks va très bien et avec moins de code et le maintien des normes MVVM

28
Adam

Aucune de ces choses ne fonctionnait pour moi exactement, mais pour le bénéfice des autres, c'est ce que j'ai fini par écrire sur la base du code déjà fourni ici.

L'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
}
17
Leo Vildosola

Ceci est un vieux fil, mais il ne semble pas exister de réponse avec du code qui réponde aux problèmes de la réponse acceptée par 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 définissez à nouveau à true. Je ne pouvais pas obtenir la solution de Zamotic pour travailler de manière fiable dans ces cas non plus.

En réunissant certaines des discussions ci-dessus, je pense que le code ci-dessous résout ces problèmes:

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, 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 façon, donc peut-être que codebehind est la voie à suivre.

11
Rich N

Dans mon cas, FocusExtension ne fonctionnait pas jusqu'à ce que je modifie la méthode OnIsFocusedPropertyChanged. L'original ne fonctionnait que dans le 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 se produit. Avec cette petite modification et l'aide de notre ami Task, cela fonctionne très 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
Vincent Rithner

Le code brillant Anvakas est destiné aux applications du bureau Windows. Si vous êtes comme moi et que vous avez besoin de la même solution pour les applications du Windows Store, ce code peut s'avérer utile:

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
PEK

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 link

2
Shawn

J'utilise WPF/Caliburn Micro et ai constaté que "dfaivre" était une solution générale et pratique Ici: http://caliburnmicro.codeplex.com/discussions/222892

1
kpp

J'ai trouvé la solution en éditant le code comme suit. Il n'est pas nécessaire de définir la propriété Binding en premier sur False, puis sur 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);
        }
    }
}
1
Bharat Mendapara

Pour ceux qui essayaient d'utiliser la solution d'Anvaka ci-dessus, je rencontrais des problèmes avec la liaison ne fonctionnant que la première fois, car lostfocus ne mettrait pas à jour la propriété. 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é:

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

De cette façon, vous aurez seulement besoin de le définir sur true, et cela obtiendra le focus.

1
Tyrsius

Faites juste ceci:

<Window x:class...
   ...
   ...
   FocusManager.FocusedElement="{Binding ElementName=myTextBox}"
>
<Grid>
<TextBox Name="myTextBox"/>
...
0
Zoltan

Personne ne semble avoir inclus la dernière étape pour faciliter la mise à jour des attributs via des variables liées. Voici ce que je suis venu avec. Faites-moi savoir s'il existe un meilleur moyen 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
Hugh

Après avoir mis en œuvre la réponse acceptée, j'ai rencontré un problème qui, lors de la navigation dans les vues avec Prism, ne restait pas le focus. Un changement mineur au gestionnaire PropertyChanged l'a résolu

    private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var uie = (UIElement)d;
        if ((bool)e.NewValue)
        {
            uie.Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
            {
                uie.Focus();
            }));
        }
    }
0
Joe H

Tout d'abord, j'aimerais 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'avais était que si vous cliquez d'abord dans votre vue et concentrez le contrôle, e.oldValue n'est plus nul. 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 est la suivante:

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
user2127475

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 à l'aide de commandes.

Je l'ai implémenté sur la base de la proposition 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. Il s’agit essentiellement de l’autre direction des commandes normales, dans les cas où un ViewModel doit effectuer une action dans sa vue. Il utilise des réflexions telles que les commandes liées aux données et WeakReferences pour éviter les fuites de mémoire.

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

0
ygoe

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>

OR

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

Pour définir le focus doit juste le faire dans le code:

EmailFocus = true;

Rappelez-vous que ce plugin fait partie d’une page html, d’autres contrôles de la page peuvent donc avoir le focus.

if (!Application.Current.IsRunningOutOfBrowser)
{
    System.Windows.Browser.HtmlPage.Plugin.Focus();
}
0
ADM-IT

J'ai trouvé la solution de Crucial au problème IsVisible très utile. Cela n'a pas complètement résolu mon problème, mais certains codes supplémentaires suivant le même modèle que le modèle IsEnabled l'ont fait.

À la méthode IsFocusedChanged, j'ai ajouté:

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

Et voici le gestionnaire:

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
Wayne Maurer