.net - visual - seleccionar texto textbox vba excel
¿Cómo seleccionar automáticamente todo el texto centrado en el cuadro de texto WPF? (28)
¡GUAUU!Después de leer todo lo anterior me encuentro abrumado y confundido. Tomé lo que pensé que aprendí en este post y probé algo completamente diferente. Para seleccionar el texto en un cuadro de texto cuando se enfoca, uso esto:
private void TextField_GotFocus(object sender, RoutedEventArgs e)
{
TextBox tb = (sender as Textbox);
if(tb != null)
{
e.Handled = true;
tb.Focus();
tb.SelectAll();
}
}
Establezca la propiedad GotFocus del cuadro de texto para este método.
Ejecutar la aplicación y hacer clic una vez en el cuadro de texto resalta todo lo que ya está en el cuadro de texto.
Si de hecho, el objetivo es seleccionar el texto cuando el usuario hace clic en el cuadro de texto, esto parece simple e implica mucho menos código. Solo digo...
Si llamo a SelectAll
desde un controlador de eventos GotFocus
, no funciona con el mouse, la selección desaparece tan pronto como se suelta el mouse.
EDITAR: A la gente le gusta la respuesta de Donnelle, trataré de explicar por qué no me gustó tanto como la respuesta aceptada.
- Es más complejo, mientras que la respuesta aceptada hace lo mismo de una manera más simple.
- La usabilidad de la respuesta aceptada es mejor. Cuando hace clic en el centro del texto, el texto se deselecciona cuando suelta el mouse, lo que le permite comenzar a editar al instante y, si aún desea seleccionar todo, solo presione el botón nuevamente y esta vez no se deseleccionará al lanzar. Siguiendo la receta de Donelle, si hago clic en el medio del texto, tengo que hacer clic en la segunda vez para poder editar. Si hago clic en algún lugar dentro del texto frente a fuera del texto, es probable que esto signifique que quiero comenzar a editar en lugar de sobrescribirlo todo.
Aquí están los comportamientos de Blend que implementan la solución de respuesta para su conveniencia:
Uno para adjuntar a un solo cuadro de texto:
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;
}
}
}
Y uno para adjuntar a la raíz de un contenedor que contiene varios TextBox''es:
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();
}
}
Aquí hay una muy buena solución muy simple en MSDN :
<TextBox
MouseDoubleClick="SelectAddress"
GotKeyboardFocus="SelectAddress"
PreviewMouseLeftButtonDown="SelectivelyIgnoreMouseButton" />
Aquí está el código detrá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();
}
}
}
Aunque esta es una pregunta antigua, acabo de tener este problema pero lo resolví utilizando un Comportamiento Adjunto, en lugar de un Comportamiento de Expresión como en la respuesta de Sergey. Esto significa que no necesito una dependencia en System.Windows.Interactivity
en el SDK de Blend:
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();
}
}
Luego puedes usarlo en tu XAML así:
<TextBox Text="Some Text" behaviors:TextBoxBehavior.SelectAllTextOnFocus="True"/>
Lo escribí here .
Creo que esto funciona 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 desea implementarlo como un método de extensión:
public static void SelectAllText(this System.Windows.Controls.TextBox tb)
{
tb.Dispatcher.BeginInvoke(
new Action(delegate
{
tb.SelectAll();
}), System.Windows.Threading.DispatcherPriority.Input);
}
Y en tu evento GotFocus:
private void ValueText_GotFocus(object sender, RoutedEventArgs e)
{
TextBox tb = (TextBox)e.OriginalSource;
tb.SelectAllText();
}
Descubrí la solución anterior porque hace varios meses estaba buscando una manera de enfocar un determinado UIElement. Descubrí el código de abajo en alguna parte (se da crédito aquí) y funciona bien. Lo publico aunque no esté directamente relacionado con la pregunta del OP porque demuestra el mismo patrón de uso de Dispatcher para trabajar con un UIElement.
// 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);
}
Esta implementación simple funciona perfectamente para mí:
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 aplicarlo a todos los TextBox
, coloque el siguiente código después de InitializeComponent();
EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(TextBox_GotFocus));
EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseDownEvent, new MouseButtonEventHandler(TextBox_PreviewMouseDown));
Esto es bastante viejo, pero voy a mostrar mi respuesta de todos modos.
He elegido parte de la respuesta de Donnelle (omití el doble clic) porque creo que esto crea el menor asombro en los usuarios. Sin embargo, como gcores, no me gusta la necesidad de crear una clase derivada. Pero tampoco me gustan los gcores "en el método de inicio ...". Y necesito esto en una base "generalmente pero no siempre".
He implementado esto como una propiedad de dependencia adjunta, por lo que puedo establecer SelectTextOnFocus.Active=True
en xaml. Me parece de esta manera el más agradable.
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 mi característica "general pero no siempre" establezco esta propiedad en Verdadero en un estilo de cuadro de texto (global). De esta manera, "seleccionar el texto" siempre está "activado", pero puedo desactivarlo por cada cuadro de texto.
La respuesta de Donnelle funciona mejor, pero tener que derivar una nueva clase para usarla es un dolor.
En lugar de hacerlo, registro los controladores en Hand.xaml.cs para todos los TextBoxes de la aplicación. Esto me permite usar la respuesta de Donnelle con el control de TextBox estándar.
Agregue los siguientes métodos a su 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();
}
}
Lo tenemos así que el primer clic selecciona todo y otro clic va al cursor (nuestra aplicación está diseñada para usarse en tabletas con bolígrafos).
Tu podrias encontrar esto útil.
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();
}
}
Me doy cuenta de que esto es muy antiguo, pero aquí está mi solución que se basa en las expresiones / interactividad de microsoft y espacios de nombres de interacciones.
Primero, seguí las instrucciones en este enlace para colocar los activadores de interactividad en un estilo.
Entonces todo se reduce a esto
<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>
y esto
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;
}
}
En mi caso, tengo un control de usuario donde están los cuadros de texto que tienen un código subyacente. El código subyacente tiene la función de controlador. Le di a mi control de usuario un nombre en xaml, y estoy usando ese nombre para el elemento. Esto está funcionando perfectamente para mí. Simplemente aplique el estilo a cualquier cuadro de texto donde desee seleccionar todo el texto al hacer clic en el cuadro de texto.
El primer CallMethodAction llama a la función SelectAll del cuadro de texto cuando se activa el evento GotKeyboardFocus en el cuadro de texto.
Espero que esto ayude.
No he encontrado ninguna de las respuestas presentadas aquí que imita un cuadro de texto estándar de Windows. Por ejemplo, intente hacer clic en el espacio en blanco entre el último carácter del cuadro de texto y el lado derecho del cuadro de texto. La mayoría de las soluciones aquí siempre seleccionarán todo el contenido, lo que hace que sea muy difícil agregar texto a un cuadro de texto.
La respuesta que presento aquí se comporta mejor a este respecto. Es un comportamiento (por lo que requiere el ensamblado System.Windows.Interactivity del Blend SDK ). También se puede reescribir usando propiedades adjuntas.
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;
}
}
Esto se basa en el código que he encontrado here .
No sé por qué pierde la selección en el evento GotFocus.
Pero una solución es hacer la selección en los eventos GotKeyboardFocus y GotMouseCapture. De esa manera siempre funcionará.
Para aquellos interesados en el enfoque de Donnelle / Groky, pero quieren un clic a la derecha del último carácter (pero aún dentro del TextBox) para colocar el cursor al final del texto ingresado, he encontrado esta solución:
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();
}
El método GetRoundedCharacterIndexFromPoint se tomó de this publicación.
Pruebe este método de extensión para agregar el comportamiento deseado a cualquier control TextBox. Todavía no lo he probado mucho, pero parece satisfacer mis necesidades.
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();
}
}
}
}
Tengo una respuesta un poco simplificada para esto (con solo el evento PreviewMouseLeftButtonDown) que parece imitar la funcionalidad habitual de un navegador:
En xaml tienes un cuadro de texto que dice:
<TextBox Text="http://www.blabla.com" BorderThickness="2" BorderBrush="Green" VerticalAlignment="Center" Height="25"
PreviewMouseLeftButtonDown="SelectAll" />
En codebehind:
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();
}
}
Tomado de madprops.org/blog/wpf-textbox-selectall-on-focus :
Registre el controlador de eventos global en el archivo App.xaml.cs:
protected override void OnStartup(StartupEventArgs e)
{
EventManager.RegisterClassHandler(typeof(TextBox),TextBox.GotFocusEvent,
new RoutedEventHandler(TextBox_GotFocus));
base.OnStartup(e);
}
Entonces el manejador es tan simple como:
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
(sender as TextBox).SelectAll();
}
en el archivo App.xaml
<Application.Resources>
<Style TargetType="TextBox">
<EventSetter Event="GotKeyboardFocus" Handler="TextBox_GotKeyboardFocus"/>
</Style>
</Application.Resources>
en el archivo App.xaml.cs
private void TextBox_GotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e)
{
((TextBox)sender).SelectAll();
}
Con este código alcanzas todos los TextBox en tu Aplicación.
Esta es, con mucho, la solución más simple.
Agregue un controlador global a la aplicación (App.xaml.cs) y listo. Sólo necesitarás unas pocas líneas de código.
protected override void OnStartup(StartupEventArgs e)
{
EventManager.RegisterClassHandler(typeof(TextBox),
TextBox.GotFocusEvent,
new RoutedEventHandler(TextBox_GotFocus));
base.OnStartup(e);
}
Utilice la clase EventManager para registrar un controlador de eventos global contra un tipo (TextBox). El manejador real es muerto simple:
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
(sender as TextBox).SelectAll();
}
Marque aquí: madprops.org/blog/wpf-textbox-selectall-on-focus
Espero eso ayude.
He usado la respuesta de Nils pero me he convertido en más 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);
}
}
En XAML, puedes usar como uno de estos:
<!-- 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" />
Intente poner esto en el constructor de cualquier control que contenga su cuadro de texto:
Loaded += (sender, e) =>
{
MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
myTextBox.SelectAll();
}
Los he probado todos, pero solo los siguientes funcionaron:
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();
}
Sergei.
Después de googlear y probar, encontré una solución simple que funcionó para mí.
Debe agregar un controlador de eventos al evento "Cargado" de su ventana de contenedor:
private void yourwindow_Loaded(object sender, RoutedEventArgs e)
{
EventManager.RegisterClassHandler(typeof(TextBox),
TextBox.PreviewMouseLeftButtonDownEvent,
new RoutedEventHandler(SelectivelyIgnoreMouseButton));
}
A continuación, debe crear el controlador para el RoutedEventHandler al que se hace referencia en el 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();
}
}
}
Ahora, puede agregar el comando SelectAll () en los controladores de eventos GotFocus a cualquier control TextBox por separado:
private void myTextBox_GotFocus(object sender, RoutedEventArgs e)
{
(sender as TextBox).SelectAll();
}
¡Tu texto ahora está seleccionado en foco!
Adaptado de la solución Dr. WPF, foros de MSDN
Una forma fácil de anular el mouseDown y seleccionar todo después de hacer doble clic es:
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();
}
}
Aquí está la versión C # de la answer publicada 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);
}
mientras que MyTextBox_GotFocus
es el controlador de eventos asignado al GotFocus
evento de MyTextBox
.
Busqué mucho en la solución, encontré algunas soluciones para seleccionar, pero el problema es cuando hacemos clic con el botón derecho y cortamos / copiamos después de seleccionar parte del texto del cuadro de texto, selecciona todo, incluso seleccioné parte del texto. Para solucionar este problema aquí está la solución. Solo agregue el siguiente código en el evento de selección de teclado. Esto funcionó para mí.
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();
}
Esto parece funcionar bien para mí. Es básicamente un resumen de algunos mensajes anteriores. Acabo de poner esto en mi archivo MainWindow.xaml.cs en el constructor. Creo dos manejadores, uno para el teclado y otro para el mouse, y canalizo ambos eventos a la misma función HandleGotFocusEvent
, que se define justo después del constructor en el mismo archivo.
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();
}
Tuve el mismo problema En VB.Net funciona de esa manera fácil:
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 # (gracias a ViRuSTriNiTy)
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);
}
#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