Comment sélectionner automatiquement tous les textes sur focus dans la boîte de texte WPF?

si j'appelle SelectAll d'un gestionnaire d'événements GotFocus , cela ne fonctionne pas avec la souris - la sélection disparaît dès que la souris est relâchée.

EDIT: les gens aiment la réponse de Donnelle, je vais essayer d'expliquer pourquoi je ne l'ai pas aimé autant que la réponse acceptée.

  • c'est plus complexe, alors que la réponse acceptée fait la même chose d'une manière plus simple.
  • La convivialité de réponse est acceptée mieux. Lorsque vous cliquez au milieu du texte, le texte est désélectionné lorsque vous relâchez la souris vous permettant de commencer à éditer instantanément, et si vous voulez toujours sélectionner tout, appuyez simplement sur le bouton à nouveau et cette fois, il ne sera pas désélectionner à la libération. Suivant la recette de Donelle, si je clique au milieu du texte, je dois cliquer la deuxième fois pour pouvoir éditer. Si je clique quelque part dans le texte par opposition à l'extérieur du texte, cela signifie très probablement que je veux commencer à éditer au lieu de réécrire tout.
194
demandé sur BigM 0000-00-00 00:00:00

28 réponses

ne sait pas pourquoi il perd la sélection dans L'événement GotFocus.

mais une solution est de faire la sélection sur les événements GotKeyboardFocus et GotMouseCapture. De cette façon, il sera toujours.

66
répondu gcores 2009-03-19 00:27:32

nous l'avons donc le premier clic sélectionne tout, et un autre clic va au curseur (notre application est conçue pour une utilisation sur les tablettes avec des stylos).

vous pourriez le trouver utile.

public class ClickSelectTextBox : TextBox
{
    public ClickSelectTextBox()
    {
        AddHandler(PreviewMouseLeftButtonDownEvent, 
          new MouseButtonEventHandler(SelectivelyIgnoreMouseButton), true);
        AddHandler(GotKeyboardFocusEvent, 
          new RoutedEventHandler(SelectAllText), true);
        AddHandler(MouseDoubleClickEvent, 
          new RoutedEventHandler(SelectAllText), true);
    }

    private static void SelectivelyIgnoreMouseButton(object sender, 
                                                     MouseButtonEventArgs e)
    {
        // Find the TextBox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        if (parent != null)
        {
            var textBox = (TextBox)parent;
            if (!textBox.IsKeyboardFocusWithin)
            {
                // If the text box is not yet focussed, give it the focus and
                // stop further processing of this click event.
                textBox.Focus();
                e.Handled = true;
            }
        }
    }

    private static void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }
}
193
répondu Donnelle 2009-06-03 08:41:56

la réponse de Donnelle fonctionne le mieux, mais avoir à dériver une nouvelle classe pour l'utiliser est une douleur.

au lieu de faire cela, j'enregistre les handlers dans App.XAML.cs pour toutes les boîtes de texte de l'application. Cela me permet d'utiliser la réponse de Donnelle avec le contrôle standard de la boîte de texte.

ajoutez les méthodes suivantes à votre application.XAML.cs:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e) 
    {
        // Select the text in a TextBox when it receives focus.
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseLeftButtonDownEvent,
            new MouseButtonEventHandler(SelectivelyIgnoreMouseButton));
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotKeyboardFocusEvent, 
            new RoutedEventHandler(SelectAllText));
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.MouseDoubleClickEvent,
            new RoutedEventHandler(SelectAllText));
        base.OnStartup(e); 
    }

    void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
    {
        // Find the TextBox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        if (parent != null)
        {
            var textBox = (TextBox)parent;
            if (!textBox.IsKeyboardFocusWithin)
            {
                // If the text box is not yet focused, give it the focus and
                // stop further processing of this click event.
                textBox.Focus();
                e.Handled = true;
            }
        }
    }

    void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }
}
145
répondu Grokys 2015-06-30 21:40:14

c'est un peu vieux, mais je vais quand même afficher ma réponse.

J'ai choisi une partie de la réponse de Donnelle (j'ai sauté le double-clic) car je pense que cela crée le moins d'étonnement dans les utilisateurs. Cependant, comme gercores Je n'aime pas la nécessité de créer une classe dérivée. Mais je n'aime pas non plus gercores "au démarrage..." méthode. Et j'en ai besoin "en général, mais pas toujours".

j'ai implémenté ceci comme une propriété de dépendance attachée pour que je puisse set SelectTextOnFocus.Active=True dans le code xaml. Je trouve cette façon la plus agréable.

namespace foo.styles.behaviour
{
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media;

    public class SelectTextOnFocus : DependencyObject
    {
        public static readonly DependencyProperty ActiveProperty = DependencyProperty.RegisterAttached(
            "Active",
            typeof(bool),
            typeof(SelectTextOnFocus),
            new PropertyMetadata(false, ActivePropertyChanged));

        private static void ActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is TextBox)
            {
                TextBox textBox = d as TextBox;
                if ((e.NewValue as bool?).GetValueOrDefault(false))
                {
                    textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;
                    textBox.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
                }
                else
                {
                    textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;
                    textBox.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDown;
                }
            }
        }

        private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DependencyObject dependencyObject = GetParentFromVisualTree(e.OriginalSource);

            if (dependencyObject == null)
            {
                return;
            }

            var textBox = (TextBox)dependencyObject;
            if (!textBox.IsKeyboardFocusWithin)
            {
                textBox.Focus();
                e.Handled = true;
            }
        }

        private static DependencyObject GetParentFromVisualTree(object source)
        {
            DependencyObject parent = source as UIElement;
            while (parent != null && !(parent is TextBox))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }

            return parent;
        }

        private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
        {
            TextBox textBox = e.OriginalSource as TextBox;
            if (textBox != null)
            {
                textBox.SelectAll();
            }
        }

        [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
        [AttachedPropertyBrowsableForType(typeof(TextBox))]
        public static bool GetActive(DependencyObject @object)
        {
            return (bool) @object.GetValue(ActiveProperty);
        }

        public static void SetActive(DependencyObject @object, bool value)
        {
            @object.SetValue(ActiveProperty, value);
        }
    }
}

Pour mon "général, mais pas toujours"-je définissez cette Propriété sur True dans un (global) zone de texte de Style. De cette façon," selecting the Text "est toujours" on", mais je peux le désactiver sur la base d'une boîte de texte.

68
répondu Nils 2015-07-14 21:21:58

Voici les comportements de mélange mettant en œuvre la solution de réponse pour votre commodité:

un pour fixation à une seule boîte de texte:

public class SelectAllTextOnFocusBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.GotKeyboardFocus += AssociatedObjectGotKeyboardFocus;
        AssociatedObject.GotMouseCapture += AssociatedObjectGotMouseCapture;
        AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObjectPreviewMouseLeftButtonDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.GotKeyboardFocus -= AssociatedObjectGotKeyboardFocus;
        AssociatedObject.GotMouseCapture -= AssociatedObjectGotMouseCapture;
        AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObjectPreviewMouseLeftButtonDown;
    }

    private void AssociatedObjectGotKeyboardFocus(object sender,
        System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        AssociatedObject.SelectAll();
    }

    private void AssociatedObjectGotMouseCapture(object sender,
        System.Windows.Input.MouseEventArgs e)
    {
        AssociatedObject.SelectAll();   
    }

    private void AssociatedObjectPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if(!AssociatedObject.IsKeyboardFocusWithin)
        {
            AssociatedObject.Focus();
            e.Handled = true;
        }
    }
}

et une autre pour fixation à la racine d'un conteneur contenant plusieurs boîtes de texte:

public class SelectAllTextOnFocusMultiBehavior : Behavior<UIElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.GotKeyboardFocus += HandleKeyboardFocus;
        AssociatedObject.GotMouseCapture += HandleMouseCapture;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.GotKeyboardFocus -= HandleKeyboardFocus;
        AssociatedObject.GotMouseCapture -= HandleMouseCapture;
    }

    private static void HandleKeyboardFocus(object sender,
        System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        var txt = e.NewFocus as TextBox;
        if (txt != null)
            txt.SelectAll();
    }

    private static void HandleMouseCapture(object sender,
        System.Windows.Input.MouseEventArgs e)
    {
        var txt = e.OriginalSource as TextBox;
        if (txt != null)
            txt.SelectAll();
    }
}
40
répondu Sergey Aldoukhov 2014-02-25 04:09:25

Voici une très bonne solution très simple sur MSDN :

<TextBox
    MouseDoubleClick="SelectAddress"
    GotKeyboardFocus="SelectAddress"
    PreviewMouseLeftButtonDown="SelectivelyIgnoreMouseButton" />

voici le code derrière:

private void SelectAddress(object sender, RoutedEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        tb.SelectAll();
    }
}

private void SelectivelyIgnoreMouseButton(object sender,
    MouseButtonEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        if (!tb.IsKeyboardFocusWithin)
        {
            e.Handled = true;
            tb.Focus();
        }
    }
}
14
répondu BillBR 2013-05-02 00:42:45

bien que ce soit une vieille question, je viens d'avoir ce problème mais résolu en utilisant un comportement attaché, plutôt qu'un comportement D'Expression comme dans la réponse de Sergey. Cela signifie que je n'ai pas besoin d'une dépendance sur System.Windows.Interactivity dans le mélange SDK:

public class TextBoxBehavior
{
    public static bool GetSelectAllTextOnFocus(TextBox textBox)
    {
        return (bool)textBox.GetValue(SelectAllTextOnFocusProperty);
    }

    public static void SetSelectAllTextOnFocus(TextBox textBox, bool value)
    {
        textBox.SetValue(SelectAllTextOnFocusProperty, value);
    }

    public static readonly DependencyProperty SelectAllTextOnFocusProperty =
        DependencyProperty.RegisterAttached(
            "SelectAllTextOnFocus",
            typeof (bool),
            typeof (TextBoxBehavior),
            new UIPropertyMetadata(false, OnSelectAllTextOnFocusChanged));

    private static void OnSelectAllTextOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textBox = d as TextBox;
        if (textBox == null) return;

        if (e.NewValue is bool == false) return;

        if ((bool) e.NewValue)
        {
            textBox.GotFocus += SelectAll;
            textBox.PreviewMouseDown += IgnoreMouseButton;
        }
        else
        {
            textBox.GotFocus -= SelectAll;
            textBox.PreviewMouseDown -= IgnoreMouseButton;
        }
    }

    private static void SelectAll(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox == null) return;
        textBox.SelectAll();
    }

    private static void IgnoreMouseButton(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        var textBox = sender as TextBox;
        if (textBox == null || textBox.IsKeyboardFocusWithin) return;

        e.Handled = true;
        textBox.Focus();
    }
}

vous pouvez alors l'utiliser dans votre XAML comme ceci:

<TextBox Text="Some Text" behaviors:TextBoxBehavior.SelectAllTextOnFocus="True"/>

j'ai blogué à ce sujet ici .

12
répondu Dutts 2013-11-12 10:41:33

je pense que cela fonctionne bien:

private void ValueText_GotFocus(object sender, RoutedEventArgs e)
    {
        TextBox tb = (TextBox)e.OriginalSource;
        tb.Dispatcher.BeginInvoke(
            new Action(delegate
                {
                    tb.SelectAll();
                }), System.Windows.Threading.DispatcherPriority.Input);
    }

si vous souhaitez l'implémenter comme une méthode d'extension:

public static void SelectAllText(this System.Windows.Controls.TextBox tb)
    {
        tb.Dispatcher.BeginInvoke(
            new Action(delegate
            {
                tb.SelectAll();
            }), System.Windows.Threading.DispatcherPriority.Input);
    }

et dans votre événement GotFocus:

private void ValueText_GotFocus(object sender, RoutedEventArgs e)
    {
        TextBox tb = (TextBox)e.OriginalSource;
        tb.SelectAllText();
    }

j'ai découvert la solution ci-dessus parce qu'il y a plusieurs mois je cherchais un moyen de mettre l'accent sur un UIElement donné. J'ai découvert le code ci-dessous quelque part (le crédit est donné par la présente) et il fonctionne bien. Je le poste même s'il n'est pas directement lié à la question de L'OP parce qu'il démontre la même tendance à utiliser le répartiteur pour travailler avec un équipement.

// Sets focus to uiElement
    public static void DelayedFocus(this UIElement uiElement)
    {
        uiElement.Dispatcher.BeginInvoke(
        new Action(delegate
        {
            uiElement.Focusable = true;
            uiElement.Focus();
            Keyboard.Focus(uiElement);
        }),
        DispatcherPriority.Render);
    }
9
répondu Sam 2012-02-24 17:46:36

Je n'ai trouvé aucune des réponses présentées ici imiter un standard Windows textbox. Par exemple, essayez de cliquer dans l'espace blanc entre le dernier caractère de la zone de texte et le côté droit de la zone de texte. La plupart des solutions ici sélectionneront toujours l'ensemble du contenu, ce qui rend très difficile l'ajout de texte à une boîte de texte.

la réponse que je présente ici se comporte mieux à cet égard. C'est un comportement (donc il nécessite le Système.Windows.Interactivité assemblage du Blend SDK ). Il pourrait être réécrite en utilisant des propriétés attachées.

public sealed class SelectAllTextOnFocusBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObject_PreviewMouseLeftButtonDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObject_PreviewMouseLeftButtonDown;
    }

    void AssociatedObject_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // Find the textbox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        var textBox = parent as TextBox;
        Debug.Assert(textBox != null);

        if (textBox.IsFocused) return;

        textBox.SelectAll();
        Keyboard.Focus(textBox);
        e.Handled = true;
    }
}

c'est basé sur le code que j'ai trouvé ici .

5
répondu Kristof Verbiest 2010-07-27 13:29:38

dans l'App.fichier xaml

<Application.Resources>
    <Style TargetType="TextBox">
        <EventSetter Event="GotKeyboardFocus" Handler="TextBox_GotKeyboardFocus"/>
    </Style>
</Application.Resources>

dans l'App.XAML.fichier cs

private void TextBox_GotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e)
    {
        ((TextBox)sender).SelectAll();
    }

avec ce code, vous accédez à tous les textes de votre Application.

5
répondu Darshan Patel 2015-07-13 10:25:20

cette simple implémentation fonctionne parfaitement pour moi:

void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    ((TextBox) sender).SelectAll();
}

void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var TextBox = (TextBox) sender;
    if (!TextBox.IsKeyboardFocusWithin)
    {
        TextBox.Focus();
        e.Handled = true;
    }
}

pour l'appliquer à tous les TextBox 's, mettez le code suivant après InitializeComponent();

EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(TextBox_GotFocus));
EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseDownEvent, new MouseButtonEventHandler(TextBox_PreviewMouseDown));
4
répondu Danny Beckett 2013-10-20 23:55:03

tiré de ici :

Register global gestionnaire d'événement dans l'App.XAML.fichier cs:

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),TextBox.GotFocusEvent,
    new RoutedEventHandler(TextBox_GotFocus));

    base.OnStartup(e);
}

alors le handler est aussi simple que:

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}
3
répondu Neomoon 2014-12-12 20:11:54

j'ai une réponse un peu simplifiée pour cela (avec juste l'événement précédent Mouseleftbuttondown) qui semble imiter la fonctionnalité habituelle d'un navigateur:

Dans le code xaml, vous avez une zone de texte pour dire:

<TextBox Text="http://www.blabla.com" BorderThickness="2" BorderBrush="Green" VerticalAlignment="Center" Height="25"
                 PreviewMouseLeftButtonDown="SelectAll" />

Dans le code-behind:

private void SelectAll(object sender, MouseButtonEventArgs e)
{

    TextBox tb = (sender as TextBox);

    if (tb == null)
    {
        return;
    }

    if (!tb.IsKeyboardFocusWithin)
    {
        tb.SelectAll();
        e.Handled = true;
        tb.Focus();
    }
}
2
répondu Danield 2011-11-29 09:46:31

pour ceux qui s'intéressent à L'approche de Donnelle/Groky, mais qui veulent un clic à droite du dernier caractère (mais toujours dans la zone de texte) pour placer le signe d'insertion à la fin du texte entré, j'ai trouvé cette solution:

    int GetRoundedCharacterIndexFromPoint(TextBox textBox, Point clickedPoint)
    {
        int position = textBox.GetCharacterIndexFromPoint(clickedPoint, true);

        // Check if the clicked point is actually closer to the next character
        // or if it exceeds the righmost character in the textbox
        // (in this case return increase the position by 1)
        Rect charLeftEdge = textBox.GetRectFromCharacterIndex(position, false);
        Rect charRightEdge = textBox.GetRectFromCharacterIndex(position, true);
        double charWidth = charRightEdge.X - charLeftEdge.X;
        if (clickedPoint.X + charWidth / 2 > charLeftEdge.X + charWidth) position++;

        return position;
    }

    void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
    {
        // Find the TextBox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        if (parent != null)
        {
            var textBox = (TextBox)parent;
            if (!textBox.IsKeyboardFocusWithin)
            {
                // If the text box is not yet focused, give it the focus and
                // stop further processing of this click event.
                textBox.Focus();
                e.Handled = true;
            }
            else
            {
                int pos = GetRoundedCharacterIndexFromPoint(textBox, e.GetPosition(textBox));
                textBox.CaretIndex = pos;
            }
        }
    }

    void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }

la méthode GetRoundedCharacterIndexFromPoint a été tirée de this post.

1
répondu PIntag 2017-05-23 12:10:33
    #region TextBoxIDCard selection
    private bool textBoxIDCardGotFocus = false;
    private void TextBoxIDCard_GotFocus(object sender, RoutedEventArgs e)
    {
        this.TextBoxIDCard.SelectAll();
    }

    private void TextBoxIDCard_LostFocus(object sender, RoutedEventArgs e)
    {
        textBoxIDCardGotFocus = false;
    }

    private void TextBoxIDCard_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (textBoxIDCardGotFocus == false)
        {
            e.Handled = true;
            this.TextBoxIDCard.Focus();
            textBoxIDCardGotFocus = true;
        }
    } 
    #endregion
1
répondu Brian 2012-01-28 17:11:07

essayez cette méthode d'extension pour ajouter le comportement désiré à n'importe quelle commande TextBox. Je ne l'ai pas encore testé en profondeur, mais il semble répondre à mes besoins.

public static class TextBoxExtensions
{
    public static void SetupSelectAllOnGotFocus(this TextBox source)
    {
        source.GotFocus += SelectAll;
        source.PreviewMouseLeftButtonDown += SelectivelyIgnoreMouseButton;
    }

    private static void SelectAll(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }

    private static void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
    {
        var textBox = (sender as TextBox);
        if (textBox != null)
        {
            if (!textBox.IsKeyboardFocusWithin)
            {
                e.Handled = true;
                textBox.Focus();
            }
        }
    }
}
1
répondu David Kirkland 2012-03-14 00:23:34

j'ai cherché beaucoup la solution, j'ai trouvé quelques solutions pour selectall mais, le problème est quand nous faisons clic droit et faire couper/copier après avoir sélectionné une partie du texte à partir de la zone de texte, il sélectionne tout même j'ai choisi partie de texte. Pour régler cela Voici la solution. Il suffit d'ajouter le code ci-dessous dans l'événement de sélection du clavier. Cela a fonctionné pour moi.

private static void SelectContentsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (d is TextBox)
    {
        TextBox textBox = d as TextBox;
        if ((e.NewValue as bool?).GetValueOrDefault(false))
        {
            textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;                 
        }
        else
        {
            textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;

        }
    }
}


private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
{
    if (e.KeyboardDevice.IsKeyDown(Key.Tab))
        ((TextBox)sender).SelectAll();
}
1
répondu Sambu Praveen 2017-01-23 19:38:43

j'ai utilisé la réponse de Nils mais converti en plus flexible.

public enum SelectAllMode
{

    /// <summary>
    ///  On first focus, it selects all then leave off textbox and doesn't check again
    /// </summary>
    OnFirstFocusThenLeaveOff = 0,

    /// <summary>
    ///  On first focus, it selects all then never selects
    /// </summary>
    OnFirstFocusThenNever = 1,

    /// <summary>
    /// Selects all on every focus
    /// </summary>
    OnEveryFocus = 2,

    /// <summary>
    /// Never selects text (WPF's default attitude)
    /// </summary>
    Never = 4,
}

public partial class TextBox : DependencyObject
{
    public static readonly DependencyProperty SelectAllModeProperty = DependencyProperty.RegisterAttached(
        "SelectAllMode",
        typeof(SelectAllMode?),
        typeof(TextBox),
        new PropertyMetadata(SelectAllModePropertyChanged));

    private static void SelectAllModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is System.Windows.Controls.TextBox)
        {
            var textBox = d as System.Windows.Controls.TextBox;

            if (e.NewValue != null)
            {
                textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
            }
            else
            {
                textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDown;
            }
        }
    }

    private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        DependencyObject dependencyObject = GetParentFromVisualTree(e.OriginalSource);

        if (dependencyObject == null)
            return;

        var textBox = (System.Windows.Controls.TextBox)dependencyObject;
        if (!textBox.IsKeyboardFocusWithin)
        {
            textBox.Focus();
            e.Handled = true;
        }
    }

    private static DependencyObject GetParentFromVisualTree(object source)
    {
        DependencyObject parent = source as UIElement;
        while (parent != null && !(parent is System.Windows.Controls.TextBox))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }

        return parent;
    }

    private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
    {
        var textBox = e.OriginalSource as System.Windows.Controls.TextBox;
        if (textBox == null) return;

        var selectAllMode = GetSelectAllMode(textBox);

        if (selectAllMode == SelectAllMode.Never)
        {
            textBox.SelectionStart = 0;
            textBox.SelectionLength = 0;
        }
        else
            textBox.SelectAll();

        if (selectAllMode == SelectAllMode.OnFirstFocusThenNever)
            SetSelectAllMode(textBox, SelectAllMode.Never);
        else if (selectAllMode == SelectAllMode.OnFirstFocusThenLeaveOff)
            SetSelectAllMode(textBox, null);
    }

    [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(System.Windows.Controls.TextBox))]
    public static SelectAllMode? GetSelectAllMode(DependencyObject @object)
    {
        return (SelectAllMode)@object.GetValue(SelectAllModeProperty);
    }

    public static void SetSelectAllMode(DependencyObject @object, SelectAllMode? value)
    {
        @object.SetValue(SelectAllModeProperty, value);
    }
}

dans XAML, vous pouvez utiliser comme l'un d'eux:

<!-- On first focus, it selects all then leave off textbox and doesn't check again -->
<TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenLeaveOff" />

<!-- On first focus, it selects all then never selects -->
<TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenNever" />

<!-- Selects all on every focus -->
<TextBox attprop:TextBox.SelectAllMode="OnEveryFocus" />

<!-- Never selects text (WPF's default attitude) -->
<TextBox attprop:TextBox.SelectAllMode="Never" />
1
répondu bafsar 2017-02-17 15:20:09

j'ai eu le même problème. En VB.Net il fonctionne facilement de cette façon:

VB XAML:

<TextBox x:Name="txtFilterFrequency" />

Codehind:

Private Sub txtFilterText_GotFocus(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles txtFilterText.GotFocus
    Me.Dispatcher.BeginInvoke(Sub()
                                  txtFilterText.SelectAll()
                              End Sub, DispatcherPriority.ApplicationIdle, Nothing)
End Sub

C# (merci à la Viruosité)

private delegate void TextBoxSelectAllDelegate(object sender);

private void TextBoxSelectAll(object sender)
{
    (sender as System.Windows.Controls.TextBox).SelectAll();
}

private void MyTextBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
    TextBoxSelectAllDelegate d = TextBoxSelectAll;

    this.Dispatcher.BeginInvoke(d,
        System.Windows.Threading.DispatcherPriority.ApplicationIdle, sender);
}
1
répondu Nasenbaer 2018-01-23 13:36:11

je me rends compte que c'est très ancien, mais voici ma solution qui est basée sur les expressions/microsoft interactivity et interactions noms espaces.

tout d'abord, j'ai suivi les instructions à ce lien pour placer les déclencheurs d'interactivité dans un style.

Puis il descend à ce

        <Style x:Key="baseTextBox" TargetType="TextBox">
        <Setter Property="gint:InteractivityItems.Template">
            <Setter.Value>
                <gint:InteractivityTemplate>
                    <gint:InteractivityItems>
                        <gint:InteractivityItems.Triggers>
                            <i:EventTrigger EventName="GotKeyboardFocus">
                                <ei:CallMethodAction MethodName="SelectAll"/>
                            </i:EventTrigger>
                            <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                                <ei:CallMethodAction MethodName="TextBox_PreviewMouseLeftButtonDown"
                                    TargetObject="{Binding ElementName=HostElementName}"/>
                            </i:EventTrigger>
                        </gint:InteractivityItems.Triggers>
                    </gint:InteractivityItems>
                </gint:InteractivityTemplate>
            </Setter.Value>
        </Setter>
    </Style>

et ce

    public void TextBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        TextBox tb = e.Source as TextBox;
        if((tb != null) && (tb.IsKeyboardFocusWithin == false))
        {
            tb.Focus();
            e.Handled = true;
        }
    }

dans mon cas, j'ai un contrôle d'utilisateur où le texte les boîtes sont celles qui ont un code-derrière. Le code-behind a la fonction handler. J'ai donné à mon user control un nom dans xaml, et j'utilise ce nom pour l'élément. Cela fonctionne parfaitement pour moi. Il suffit d'appliquer le style à n'importe quelle zone de texte où vous souhaitez avoir tout le texte sélectionné lorsque vous cliquez dans la zone de texte.

le premier CallMethodAction appelle la fonction SelectAll de la zone de texte lorsque L'événement GotKeyboardFocus se déclenche sur la zone de texte.

j'espère que aider.

1
répondu wiyosaya 2018-03-26 21:35:11

C'est de loin la solution la plus simple.

Ajouter un gestionnaire global à l'application (App.XAML.cs) et fait. Vous allez avoir besoin de quelques lignes de code.

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),
        TextBox.GotFocusEvent,
        new RoutedEventHandler(TextBox_GotFocus));

    base.OnStartup(e);
}

utilisez donc la classe EventManager pour enregistrer un gestionnaire d'événements global contre un type (TextBox). Le gestionnaire actuel est très simple:

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}

Vérifier ici: WPF zone de texte SelectAll sur Focus

Espérons que cela aide.

1
répondu Marlon Assef 2018-04-27 11:51:40

Cela semble bien fonctionner pour moi. C'est un résumé de quelques billets précédents. Je viens de mettre ça dans mon MainWindow.XAML.fichier cs dans le constructeur. Je crée deux handlers, l'un pour le clavier, et l'autre pour la souris, et canalisent les deux événements dans la même fonction, HandleGotFocusEvent , qui est définie juste après le constructeur dans le même fichier.

public MainWindow()
{
   InitializeComponent();

   EventManager.RegisterClassHandler(typeof(TextBox), 
      UIElement.GotKeyboardFocusEvent,
      new RoutedEventHandler(HandleGotFocusEvent), true);
   EventManager.RegisterClassHandler(typeof(TextBox),
      UIElement.GotMouseCaptureEvent,
      new RoutedEventHandler(HandleGotFocusEvent), true);   
}
private void HandleGotFocusEvent(object sender, RoutedEventArgs e)
{
   if (sender is TextBox)
      (sender as TextBox).SelectAll();
}
0
répondu Ted 2012-11-23 16:05:11

un moyen facile de surcharger le mouseDown et de sélectionner tout après doubleclick est:

public class DoubleClickTextBox: TextBox
{

    public override void EndInit()
    {
        base.EndInit();            
    }

    protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
    {
        base.OnMouseEnter(e);
        this.Cursor = Cursors.Arrow;
    }
    protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
    {

    }

    protected override void OnMouseDoubleClick(System.Windows.Input.MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);
        this.SelectAll();
    }
}
0
répondu Hesse 2012-11-29 11:38:48

essayez de mettre ceci dans le constructeur de n'importe quel contrôle qui abrite votre textbox:

Loaded += (sender, e) =>
{
    MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    myTextBox.SelectAll();
}
0
répondu CodeOtaku 2015-01-30 19:57:21

Sergei.

après googler et tester, j'ai trouvé une solution simple qui a fonctionné pour moi.

vous devez ajouter un gestionnaire d'événements à l'événement "chargé" de votre fenêtre de conteneur:

    private void yourwindow_Loaded(object sender, RoutedEventArgs e)
    {
        EventManager.RegisterClassHandler(typeof(TextBox),
            TextBox.PreviewMouseLeftButtonDownEvent,
            new RoutedEventHandler(SelectivelyIgnoreMouseButton));
    }

ensuite, vous devez créer le gestionnaire pour le RoutedEventHandler référencé dans le code précédent:

    private void SelectivelyIgnoreMouseButton(object sender, RoutedEventArgs e)
    {
        TextBox tb = (sender as TextBox);
        if (tb != null)
        {
            if (!tb.IsKeyboardFocusWithin)
            {
                e.Handled = true;
                tb.Focus();
            }
        }
    }

maintenant, vous pouvez ajouter la commande SelectAll() sur les gestionnaires D'événements GotFocus à n'importe quelle boîte de texte commandes séparées:

    private void myTextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        (sender as TextBox).SelectAll();
    }

votre texte est maintenant sélectionné sur focus!

adapté de Dr. WPF solution, MSDN Forums

0
répondu DonBeto97 2017-06-02 00:30:47

je les ai tous testés, mais seulement les suivants ont fonctionné:

        protected override void OnStartup(StartupEventArgs e) 
        {
            EventManager.RegisterClassHandler(typeof(TextBox), UIElement.PreviewMouseLeftButtonDownEvent,
           new MouseButtonEventHandler(SelectivelyHandleMouseButton), true);
            EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotKeyboardFocusEvent,
              new RoutedEventHandler(SelectAllText), true);
            EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent,
              new RoutedEventHandler(GotFocus), true);          
        }

        private static void SelectivelyHandleMouseButton(object sender, MouseButtonEventArgs e)
        {
            var textbox = (sender as TextBox);
            if (textbox != null)
            {
                int hc = textbox.GetHashCode();
                if (hc == LastHashCode)
                {
                    if (e.OriginalSource.GetType().Name == "TextBoxView")
                    {
                        e.Handled = true;
                        textbox.Focus();
                        LastHashCode = -1;
                    }
                }
            }
            if (textbox != null) textbox.Focus();
        }

        private static void SelectAllText(object sender, RoutedEventArgs e)
        {
            var textBox = e.OriginalSource as TextBox;
            if (textBox != null)
                textBox.SelectAll();
        }

        private static int LastHashCode;
        private static void GotFocus(object sender, RoutedEventArgs e)
        {
            var textBox = e.OriginalSource as TextBox;
            if (textBox != null)
                LastHashCode = textBox.GetHashCode();
        }
-1
répondu Ehsan Zargar Ershadi 2010-07-28 09:41:38

WOW! Après avoir lu tout ce qui précède, je me sens accablé et confus. J'ai pris ce que je pensais, j'ai appris dans ce post et a essayé quelque chose de complètement différent. Pour sélectionner le texte dans une boîte de texte quand il obtient la mise au point j'utilise ceci:

private void TextField_GotFocus(object sender, RoutedEventArgs e)
{
    TextBox tb = (sender as Textbox);
    if(tb != null)
    {
        e.Handled = true;
        tb.Focus();
        tb.SelectAll();
    }
}

définit la propriété GotFocus de la textbox à cette méthode.

exécuter l'application et cliquer une fois dans la zone de texte met en évidence tout ce qui se trouve déjà dans la zone de texte.

si en effet, l'objectif est de sélectionner le texte lorsque l'utilisateur clique dans la boîte de texte, cela semble simple et implique beaucoup moins de code. Juste pour dire...

-1
répondu GAMinTN 2014-12-30 19:44:02