.net - net - vba selecionar caixa de texto




Como selecionar automaticamente todo o texto em foco no WPF TextBox? (19)

A resposta de Donnelle funciona melhor, mas ter que derivar uma nova classe para usá-la é uma dor.

Em vez de fazer isso, registro os manipuladores nos manipuladores App.xaml.cs para todos os TextBoxes no aplicativo. Isso me permite usar a resposta de um Donnelle com o controle TextBox padrão.

Adicione os seguintes métodos ao seu App.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();
    }
}

Se eu chamo SelectAll de um manipulador de eventos GotFocus , ele não funciona com o mouse - a seleção desaparece assim que o mouse é liberado.

EDIT: As pessoas estão gostando da resposta de Donnelle, vou tentar explicar porque eu não gostei tanto quanto a resposta aceita.

  • É mais complexo, enquanto a resposta aceita faz a mesma coisa de maneira mais simples.
  • A usabilidade da resposta aceita é melhor. Quando você clica no meio do texto, o texto fica desmarcado quando você solta o mouse, permitindo que você comece a editar instantaneamente, e se você ainda quiser selecionar todos, basta pressionar o botão novamente e desta vez não será desmarcado no lançamento. Seguindo a receita de Donelle, se eu clicar no meio do texto, eu tenho que clicar na segunda vez para poder editar. Se eu clicar em algum lugar dentro do texto versus fora do texto, isso provavelmente significa que quero começar a editar em vez de sobrescrever tudo.

Aqui está uma solução muito boa e muito simples no MSDN :

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

Aqui está o código por trás:

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();
        }
    }
}

Embora essa seja uma pergunta antiga, acabei de ter esse problema, mas o resolvi usando um Attached Behavior, em vez de um Expression Behavior como na resposta de Sergey. Isso significa que não preciso de uma dependência em System.Windows.Interactivity no Blend 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();
    }
}

Você pode então usá-lo em seu XAML assim:

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

Eu escrevi sobre isso here .


Esta implementação simples funciona perfeitamente para mim:

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;
    }
}

Para aplicá-lo a todos os TextBox , coloque o seguinte código após InitializeComponent();

EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(TextBox_GotFocus));
EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseDownEvent, new MouseButtonEventHandler(TextBox_PreviewMouseDown));

Eu encontrei nenhuma das respostas apresentadas aqui imitar uma caixa de texto padrão do Windows. Por exemplo, tente clicar no espaço em branco entre o último caractere da caixa de texto e o lado direito da caixa de texto. A maioria das soluções aqui sempre seleciona todo o conteúdo, o que torna muito difícil adicionar texto a uma caixa de texto.

A resposta que apresento aqui se comporta melhor a esse respeito. É um comportamento (por isso, requer o assembly System.Windows.Interactivity do Blend SDK ). Ele poderia ser reescrito usando propriedades anexadas também.

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;
    }
}

Isso é baseado no código que encontrei here .


Eu percebo que isso é muito antigo, mas aqui está a minha solução, que é baseada nas interações expressões / microsoft interatividade e espaços de nomes de interações.

Primeiro, eu segui as instruções neste link para colocar gatilhos de interatividade em um estilo.

Então tudo se resume a isso

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

e isto

    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;
        }
    }

No meu caso, eu tenho um controle de usuário onde as caixas de texto são que tem um code-behind. O código por trás tem a função de manipulador. Eu dei ao meu controle de usuário um nome em xaml e estou usando esse nome para o elemento. Isso está funcionando perfeitamente para mim. Basta aplicar o estilo a qualquer caixa de texto onde você gostaria de ter todo o texto selecionado quando você clica na caixa de texto.

O primeiro CallMethodAction chama a função SelectAll da caixa de texto quando o evento GotKeyboardFocus na caixa de texto é acionado.

Eu espero que isso ajude.


Isso é bastante antigo, mas mostrarei minha resposta de qualquer maneira.
Eu escolhi parte da resposta de Donnelle (pulei o clique duplo) pois acho que isso cria o menor espanto entre os usuários. No entanto, como gcores eu não gosto da necessidade de criar uma classe derivada. Mas eu também não gosto do método gcores "on Startup ...". E eu preciso disso em uma base "geralmente, mas nem sempre".

Eu tenho implementado isso como uma propriedade de dependência anexada para que eu possa definir SelectTextOnFocus.Active=True in xaml. Eu acho assim o mais agradável.

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);
        }
    }
}

Para o meu "geral, mas nem sempre" -feature eu definir essa propriedade como True em um (global) TextBox-Style. Desta forma, "selecionando o texto" é sempre "on", mas eu sou capaz de desativá-lo em uma base por caixa de texto.


Não sei porque perde a seleção no evento GotFocus.

Mas uma solução é fazer a seleção nos eventos GotKeyboardFocus e GotMouseCapture. Dessa forma, sempre funcionará.


Para aqueles interessados ​​na abordagem de Donnelle / Groky, mas quer um clique à direita do último caractere (mas ainda dentro do TextBox) para colocar o cursor no final do texto digitado, eu encontrei esta solução:

    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();
    }

O método GetRoundedCharacterIndexFromPoint foi retirado this postagem.


Tirado madprops.org/blog/wpf-textbox-selectall-on-focus :

Registre o manipulador de eventos global no arquivo App.xaml.cs:

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

    base.OnStartup(e);
}

Então o manipulador é tão simples quanto:

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

no arquivo App.xaml

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

no arquivo App.xaml.cs

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

Com este código você alcança todo o TextBox em seu aplicativo.


Esta é de longe a solução mais simples.

Adicione um manipulador global ao aplicativo (App.xaml.cs) e pronto. Você precisará apenas de algumas linhas de código.

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

    base.OnStartup(e);
}

Portanto, use a classe EventManager para registrar um manipulador de eventos global em um tipo (TextBox). O manipulador real é muito simples:

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

Verifique aqui: madprops.org/blog/wpf-textbox-selectall-on-focus

Espero que ajude.


Eu usei a resposta de Nils, mas converti para mais flexível.

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);
    }
}

No XAML, você pode usar um destes:

<!-- 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" />

Sergei.

Depois de pesquisar e testar, encontrei uma solução simples que funcionou para mim.

Você precisa adicionar um manipulador de eventos ao evento "Carregado" de sua janela de contêiner:

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

Em seguida, você precisa criar o manipulador para o RoutedEventHandler de referência no código anterior:

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

Agora, você pode adicionar o comando SelectAll () em manipuladores de eventos GotFocus a qualquer controle TextBox separadamente:

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

Seu texto agora está selecionado em foco!

Adaptado da solução do Dr. WPF, MSDN Forums


Uma maneira fácil de substituir o mouseDown e selecionar todos após o doubleclick é:

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();
    }
}

Aqui está a versão C # da answer postada por @Nasenbaer

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);
}

enquanto MyTextBox_GotFocusé o manipulador de eventos atribuído ao GotFocusevento de MyTextBox.


Isso parece funcionar bem para mim. É basicamente uma recapitulação de alguns posts anteriores. Acabei de colocar isso no meu arquivo MainWindow.xaml.cs no construtor. Eu crio dois manipuladores, um para o teclado e outro para o mouse, e canalizo os dois eventos para a mesma função HandleGotFocusEvent, que é definida logo após o construtor no mesmo arquivo.

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();
}

Pesquisei muito pela solução, encontrei algumas soluções para selectall Mas, o problema é quando fazemos clique direito e cortamos / copiamos depois de selecionar parte do texto da caixa de texto, ele seleciona todos inclusive eu selecionei parte do texto. Para corrigir isso aqui é a solução. Basta adicionar o código abaixo no evento de seleção do teclado. Isso funcionou para mim.

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();
}

    #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




textbox