WPF - Remove focus when clicking outside of a textbox
To avoid code behind you can use this Behavior The behavior
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;
}
}
Useing in XAML:
On any element outside the text box that you want him to clear the focus on click add:
<i:Interaction.Behaviors>
<behaviors:ClearFocusOnClickBehavior/>
</i:Interaction.Behaviors>
Rather than adding new control to window, I think you should give your Grid a name and react to the MouseDown event on your window, moving the focus to the Grid itself. Something like this:
<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"
Background="#01FFFFFF"
KeyDown="Grid_KeyDown"
Name="grid1"
Focusable="True">
<TextBox Width="120" Margin="117,61,0,0"
Name="textBox1"
VerticalAlignment="Top"
HorizontalAlignment="Left"/>
</Grid>
</Window>
code behind:
private void window1_MouseDown(object sender, MouseButtonEventArgs e)
{
grid1.Focus();
}
I think, better way to solve this problem is adding MouseDown event handler to window with code behind:
private void window_MouseDown(object sender, MouseButtonEventArgs e)
{
Keyboard.ClearFocus();
}
Another way that worked for me was using
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler
For example, say you had a TextBlock that when clicked, should become editable by showing a focused TextBox. Then when the user clicked outside the TextBox, it should be hidden again. Here's how you can do it:
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;
}