我有一个包含文本框的UserControl。我想在用户单击按钮时以编程方式将keyboardfocus设置为此文本框。 我试过这个:
private void Button_Click(object sender,EventArgs e)
{
Keyboard.Focus(MyUserControl);
}
没有运气。然后我通过TextBox 类型的属性在UserControl中公开了Textbox
private void Button_Click(object sender,EventArgs e)
{
Keyboard.Focus(MyUserControl.TextBox);
}
再一次没有运气。最后,我在UserControl中创建了一个eventhandler来处理GotKeyboardFocus事件,在其中的文本框上调用Keyboard.Focus方法。
再次没有运气?!
怎么做?
编辑: 该问题与UserControls无关。当您尝试将焦点传递给Click或MouseDownHandler中的其他UIElement时,这是一个问题。 下面的XAML代码讲述了他们自己的故事:焦点确实传递到文本框但被列表框偷走了。
<Window x:Class="FocusSpike.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel>
<TextBox Name="FocusedTextBox" Height="30">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Text" Value="I am unfocused..."/>
<Setter Property="Opacity" Value=".3"/>
<Style.Triggers>
<Trigger Property="IsKeyboardFocused" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard AutoReverse="True">
<DoubleAnimation Storyboard.TargetProperty="FontSize" To="20"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Setter Property="Text" Value="I am focused!"/>
<Setter Property="Opacity" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<Button>Click to steal focus.</Button>
<ListBox>
<ListBoxItem GotFocus="Listbox_GotFocus">
<Label MouseDown="ListBoxItem_MouseDown">
Click to restore focus
</Label>
</ListBoxItem>
</ListBox>
</StackPanel>
</Window>
using System.Windows;
using System.Windows.Input;
namespace FocusSpike
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
FocusedTextBox.Focus();
}
private void ListBoxItem_MouseDown(object sender, MouseButtonEventArgs e)
{
Keyboard.Focus(FocusedTextBox);//This does not work, remove it!
}
private void Listbox_GotFocus(object sender, RoutedEventArgs e)
{
//Keyboard.Focus(FocusedTextBox);//uncomment to restore focus!
}
}
}
答案 0 :(得分:6)
您可以使用.Focus()
延迟实际的Dispatcher.BeginInvoke
来电,直到Focus()
或Click
事件处理程序完成并{调用代码已完成工作。
以下是如何操作:
MouseDown
以下是事件序列:
private void ListBoxItem_MouseDown(object sender, MouseButtonEventArgs e)
{
//Keyboard.Focus(FocusedTextBox); // May be necessary to uncomment this in some scenarios
Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
{
Keyboard.Focus(FocusedTextBox);
});
}
来设置焦点。这里的关键点是,在您的处理程序返回并且WPF完成所有待处理的输入处理之后才会调用 Keyboard.Focus(FocusedTextBox)
。
KeyboardFocus.Focus()
调用本身可能会触发ListBox从您那里窃取焦点。我没有检查过这个。如果是这种情况,解决方案是调用它两次:一次来自MouseDown处理程序,再次来自MouseDown处理程序调度的Action。因此,如果它对注释掉的第一行不起作用,请取消注释并重试。
答案 1 :(得分:3)
MyUserControl.FindControl("TextBox1").Focus();
失败了......
(TextBox)(MyUserControl.FindControl("TextBox1")).Focus();