如果我从GotFocus事件处理程序中调用SelectAll,它对鼠标不起作用——鼠标一释放,选择就消失了。
编辑:人们喜欢唐纳利的回答,我将试着解释为什么我不像公认的答案那样喜欢它。
It is more complex, while the accepted answer does the same thing in a simpler way.
The usability of accepted answer is better. When you click in the middle of the text, text gets unselected when you release the mouse allowing you to start editing instantly, and if you still want to select all, just press the button again and this time it will not unselect on release. Following Donelle's recipe, if I click in the middle of text, I have to click second time to be able to edit. If I click somewhere within the text versus outside of the text, this most probably means I want to start editing instead of overwriting everything.
我发现这里给出的答案都没有模仿标准的Windows文本框。例如,尝试在文本框的最后一个字符和文本框右侧之间的空白区域单击。这里的大多数解决方案总是选择整个内容,这使得将文本添加到文本框非常困难。
我在这里给出的答案在这方面表现得更好。它是一个行为(因此它需要来自Blend SDK的System.Windows.Interactivity程序集)。也可以使用附加属性重写。
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;
}
}
这是基于我在这里找到的代码。
我知道这是非常古老的,但这是我的解决方案,它是基于表达式/微软交互性和交互名称空间。
首先,我按照此链接中的说明将交互性触发器放入样式中。
然后就归结为这个
<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>
这
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;
}
}
在我的例子中,我有一个用户控件,其中的文本框有一个隐藏代码。隐藏代码具有处理程序函数。我在XAML中为用户控件设置了一个名称,并将该名称用于元素。这对我来说非常有效。简单地应用样式的任何文本框,你想有所有的文本选择时,点击在文本框。
当TextBox上的GotKeyboardFocus事件触发时,第一个CallMethodAction调用文本框的SelectAll方法。
我希望这能有所帮助。
我认为这很有效:
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);
}
如果你想实现它作为一个扩展方法:
public static void SelectAllText(this System.Windows.Controls.TextBox tb)
{
tb.Dispatcher.BeginInvoke(
new Action(delegate
{
tb.SelectAll();
}), System.Windows.Threading.DispatcherPriority.Input);
}
在GotFocus事件中:
private void ValueText_GotFocus(object sender, RoutedEventArgs e)
{
TextBox tb = (TextBox)e.OriginalSource;
tb.SelectAllText();
}
我发现上面的解决方案是因为几个月前我正在寻找一种方法来将焦点设置到给定的UIElement上。我在某处发现了下面的代码(特此给予),它工作得很好。尽管它与OP的问题没有直接关系,但我还是发布了它,因为它演示了使用Dispatcher处理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);
}
在谷歌搜索和测试之后,我找到了一个简单的解决方案。
你需要在容器窗口的Loaded事件中添加一个事件处理程序:
private void yourwindow_Loaded(object sender, RoutedEventArgs e)
{
EventManager.RegisterClassHandler(typeof(TextBox),
TextBox.PreviewMouseLeftButtonDownEvent,
new RoutedEventHandler(SelectivelyIgnoreMouseButton));
}
接下来,你必须创建之前代码中引用的RoutedEventHandler的处理程序:
private void SelectivelyIgnoreMouseButton(object sender, RoutedEventArgs e)
{
TextBox tb = (sender as TextBox);
if (tb != null)
{
if (!tb.IsKeyboardFocusWithin)
{
e.Handled = true;
tb.Focus();
}
}
}
现在,你可以单独将GotFocus事件处理程序上的SelectAll()命令添加到任何TextBox控件:
private void myTextBox_GotFocus(object sender, RoutedEventArgs e)
{
(sender as TextBox).SelectAll();
}
您的文本现在被选中对焦!
改编自博士WPF解决方案,MSDN论坛
这个简单的实现非常适合我:
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;
}
}
把它应用到所有的文本框,把下面的代码InitializeComponent();
EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(TextBox_GotFocus));
EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseDownEvent, new MouseButtonEventHandler(TextBox_PreviewMouseDown));