WPF——在文本框外单击时,删除焦点

时间:2021-12-21 19:47:34

I have some textboxes where I would like focus to behave a little differently than normal for a WPF application. Basically, I would like them to behave more like a textbox behaves on a webpage. That is, if I click anywhere outside of the textbox, it will lose its focus. What is the best way to do so?

我有一些文本框,在这些文本框中,我希望专注于WPF应用程序的行为与正常情况有所不同。基本上,我希望它们的行为更像网页上的文本框。也就是说,如果我点击文本框之外的任何地方,它就会失去焦点。最好的办法是什么?

If the answer is to programmatically remove focus, what is the best way to detect a Mouseclick outside of the bounds? What if the element I'm clicking on will be the new recipient of focus?

如果答案是以编程方式删除焦点,那么检测超出界限的鼠标单击的最佳方法是什么?如果我单击的元素将成为焦点的新接收方,该怎么办?

8 个解决方案

#1


24  

rather than adding new control to window i think you should add name to your grid and on click even of window set focus on grid 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" KeyDown="Grid_KeyDown" Name="grid1" Focusable="True">
          <TextBox HorizontalAlignment="Left" Margin="117,61,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
    </Grid>
</Window>

code behind:

背后的代码:

private void window1_MouseDown(object sender, MouseButtonEventArgs e)
{
    grid1.Focus();
}

#2


11  

I think, better way to solve this problem is adding MouseDown event handler to window with code behind:

我认为,解决这个问题的更好方法是在窗口中添加MouseDown事件处理程序:

private void window_MouseDown(object sender, MouseButtonEventArgs e)
{
    Keyboard.ClearFocus();
}

#3


3  

Another way that worked for me was using

另一种对我有用的方法是使用。

Mouse.AddPreviewMouseDownOutsideCapturedElementHandler

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:

例如,假设您有一个TextBlock,当单击时,它将通过显示焦点文本框成为可编辑的。然后,当用户在文本框外单击时,它应该再次隐藏。你可以这样做:

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;
}

#4


2  

I'm not 100% sure, but if you set Focusable to true on the container element (Grid, StackPanel, etc) then it should take the focus away from the text box.

我不是100%确定,但是如果您在容器元素(Grid、StackPanel等)上将focable设置为true,那么它应该会将焦点从文本框中移开。

#5


1  

If you clicked on the element, which can grab the focus, you get what you need. if, for example, you have some panel, you can handle panel's mouseClick event to achive your needs, or use Richard Szalay advice.

如果单击可以获取焦点的元素,就会得到所需的内容。例如,如果您有一些面板,您可以处理面板的mouseClick事件来满足您的需求,或者使用Richard Szalay的建议。

#6


0  

you cant explicitly loose the focus of a control

不能显式地释放控件的焦点

you can set the focus to other control instead

您可以将焦点设置为其他控件。

**txt.Focusable=true;
label.focus();
Keyboard.Focus(txtPassword);**

try this

试试这个

#7


0  

I was running into a similar issue, but when I wrapped my textboxes around a ScrollViewer control, all the textboxes would automatically lose focus when clicking anywhere outside the texboxes.

我遇到了一个类似的问题,但是当我在一个ScrollViewer控件周围包装我的文本框时,所有的文本框在点击文本框外的任何地方都会自动失去焦点。

#8


0  

You can use the IsKeyboardFocusedChanged event:

您可以使用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
    }
}    

#1


24  

rather than adding new control to window i think you should add name to your grid and on click even of window set focus on grid 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" KeyDown="Grid_KeyDown" Name="grid1" Focusable="True">
          <TextBox HorizontalAlignment="Left" Margin="117,61,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
    </Grid>
</Window>

code behind:

背后的代码:

private void window1_MouseDown(object sender, MouseButtonEventArgs e)
{
    grid1.Focus();
}

#2


11  

I think, better way to solve this problem is adding MouseDown event handler to window with code behind:

我认为,解决这个问题的更好方法是在窗口中添加MouseDown事件处理程序:

private void window_MouseDown(object sender, MouseButtonEventArgs e)
{
    Keyboard.ClearFocus();
}

#3


3  

Another way that worked for me was using

另一种对我有用的方法是使用。

Mouse.AddPreviewMouseDownOutsideCapturedElementHandler

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:

例如,假设您有一个TextBlock,当单击时,它将通过显示焦点文本框成为可编辑的。然后,当用户在文本框外单击时,它应该再次隐藏。你可以这样做:

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;
}

#4


2  

I'm not 100% sure, but if you set Focusable to true on the container element (Grid, StackPanel, etc) then it should take the focus away from the text box.

我不是100%确定,但是如果您在容器元素(Grid、StackPanel等)上将focable设置为true,那么它应该会将焦点从文本框中移开。

#5


1  

If you clicked on the element, which can grab the focus, you get what you need. if, for example, you have some panel, you can handle panel's mouseClick event to achive your needs, or use Richard Szalay advice.

如果单击可以获取焦点的元素,就会得到所需的内容。例如,如果您有一些面板,您可以处理面板的mouseClick事件来满足您的需求,或者使用Richard Szalay的建议。

#6


0  

you cant explicitly loose the focus of a control

不能显式地释放控件的焦点

you can set the focus to other control instead

您可以将焦点设置为其他控件。

**txt.Focusable=true;
label.focus();
Keyboard.Focus(txtPassword);**

try this

试试这个

#7


0  

I was running into a similar issue, but when I wrapped my textboxes around a ScrollViewer control, all the textboxes would automatically lose focus when clicking anywhere outside the texboxes.

我遇到了一个类似的问题,但是当我在一个ScrollViewer控件周围包装我的文本框时,所有的文本框在点击文本框外的任何地方都会自动失去焦点。

#8


0  

You can use the IsKeyboardFocusedChanged event:

您可以使用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
    }
}