我有一些文本框,我希望专注于与WPF应用程序的正常行为略有不同。基本上,我希望他们的行为更像是网页上的文本框行为。也就是说,如果我点击文本框外的任何地方,它将失去焦点。这样做的最佳方法是什么?
如果答案是以编程方式移除焦点,那么在边界外检测Mouseclick的最佳方法是什么?如果我点击的元素将成为焦点的新接收者,该怎么办?
而不是向窗口添加新控件,我认为你应该为你的Grid命名并对窗口上的MouseDown事件作出反应,将焦点移动到Grid本身。像这样的东西:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="412" Width="569" MouseDown="Window_MouseDown" Name="window1" >
<Grid ShowGridLines="False" KeyDown="Grid_KeyDown" Name="grid1" Focusable="True">
<TextBox HorizontalAlignment="Left" Margin="117,61,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
</Grid>
</Window>
代码背后:
private void window1_MouseDown(object sender, MouseButtonEventArgs e)
{
grid1.Focus();
}
我已经在原生WPF应用程序中尝试了所选答案,但由于文本框没有失去焦点,因此没有触发文本框失去焦点。以下解决方案为我工作。
将鼠标按下事件绑定到Window:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="412" Width="569" MouseDown="window_MouseDown" Name="window1" >
<Grid ShowGridLines="False" KeyDown="Grid_KeyDown" Name="grid1" Focusable="True">
<TextBox HorizontalAlignment="Left" Margin="117,61,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
</Grid>
</Window>
和事件是:
private void window_MouseDown(object sender, MouseButtonEventArgs e)
{
TextBox textBox = Keyboard.FocusedElement as TextBox;
if (textBox != null)
{
TraversalRequest tRequest = new TraversalRequest(FocusNavigationDirection.Next);
textBox.MoveFocus(tRequest);
}
}
public class ClearFocusOnOutsideClickBehavior : Behavior<FrameworkElement>
{
protected override void OnAttached()
{
AssociatedObject.GotFocus += AssociatedObjectOnGotFocus;
AssociatedObject.LostFocus += AssociatedObjectOnLostFocus;
base.OnAttached();
}
private void AssociatedObjectOnLostFocus(object sender, RoutedEventArgs e)
{
App.Current.MainWindow.MouseUp -= _paren_PreviewMouseUp;
}
private void AssociatedObjectOnGotFocus(object sender, RoutedEventArgs e)
{
App.Current.MainWindow.MouseUp += _paren_PreviewMouseUp;
}
private void _paren_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
Keyboard.ClearFocus();
}
protected override void OnDetaching()
{
AssociatedObject.GotFocus -= AssociatedObjectOnGotFocus;
AssociatedObject.LostFocus -= AssociatedObjectOnLostFocus;
}
}
在XAML中使用:
<TextBox Height="30" Width="200">
<i:Interaction.Behaviors>
<behaviours:ClearFocusOnOutsideClickBehavior/>
</i:Interaction.Behaviors>
</TextBox>
我认为,解决此问题的更好方法是将MouseDown事件处理程序添加到窗口,后面是代码:
private void window_MouseDown(object sender, MouseButtonEventArgs e)
{
Keyboard.ClearFocus();
}
另一种对我有用的方法就是使用
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler
例如,假设你有一个TextBlock,当点击时,它应该通过显示一个聚焦的TextBox变得可编辑。然后,当用户在TextBox外部单击时,应该再次隐藏它。这是你如何做到的:
private void YourTextBlock_OnMouseDown(object sender, MouseButtonEventArgs e)
{
YourTextBox.Visibility = Visibility.Visible;
YourTextBox.Focus();
CaptureMouse();
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideElement);
}
private void OnMouseDownOutsideElement(object sender, MouseButtonEventArgs e)
{
Mouse.RemovePreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideElement);
ReleaseMouseCapture();
YourTextBox.Visibility = Visibility.Hidden;
}
为避免代码隐藏,您可以使用此行为
public class ClearFocusOnClickBehavior : Behavior<FrameworkElement>
{
protected override void OnAttached()
{
AssociatedObject.MouseDown += AssociatedObject_MouseDown;
base.OnAttached();
}
private static void AssociatedObject_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Keyboard.ClearFocus();
}
protected override void OnDetaching()
{
AssociatedObject.MouseDown -= AssociatedObject_MouseDown;
}
}
在XAML中使用:
在文本框外面的任何元素上,您希望他清除焦点,单击添加:
<i:Interaction.Behaviors>
<behaviors:ClearFocusOnClickBehavior/>
</i:Interaction.Behaviors>
我不是100%肯定,但是如果你在容器元素(Grid,StackPanel等)上将Focusable
设置为true,那么它应该将焦点从文本框中移开。
如果你点击了可以抓住焦点的元素,你就可以得到你需要的东西。例如,如果你有一些面板,你可以处理面板的mouseClick事件以满足你的需求,或者使用Richard Szalay的建议。
我遇到了类似的问题,但是当我在我的文本框中包装一个ScrollViewer控件时,所有文本框在点击texbox之外的任何地方时都会自动失去焦点。
你不能明确地失去控制的焦点
您可以将焦点设置为其他控件
**txt.Focusable=true;
label.focus();
Keyboard.Focus(txtPassword);**
试试这个
你可以使用IsKeyboardFocusedChanged
事件:
myTextBox.IsKeyboardFocusedChanged += myTextBox_IsKeyboardFocusedChanged;
private void SendFileCaptionTextBox_IsKeyboardFocusedChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue.ToString() == "True")
{
// it's focused
}
else
{
// it's not focused
}
}