wpf 将焦点放回其父级?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21934347/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set focus back to its parent?
提问by herohuyongtao
From post WPF: How to programmatically remove focus from a TextBox, I know how to set a TextBox's focus back to its parent using the following code:
从 post WPF: How to programmatically remove focus from a TextBox,我知道如何TextBox使用以下代码将 a的焦点设置回其父级:
// Move to a parent that can take focus
FrameworkElement parent = (FrameworkElement)textBox.Parent;
while (parent != null && parent is IInputElement
&& !((IInputElement)parent).Focusable)
{
parent = (FrameworkElement)parent.Parent;
}
DependencyObject scope = FocusManager.GetFocusScope(textBox);
FocusManager.SetFocusedElement(scope, parent as IInputElement);
Is there any way to generalize this code (like template functions) to make it also work for other items like ComboBox, Canvas, Imageetc.
有什么办法来概括这段代码(如模板函数),使其也适用于其他项目,如工作ComboBox,Canvas,Image等。
采纳答案by Caleb Everett
It should be relatively straightforward:
它应该相对简单:
FrameworkElement ctrl = control; //or whatever you're passing in, since all controls are FrameworkElements.
// Move to a parent that can take focus
FrameworkElement parent = (FrameworkElement)ctrl.Parent;
while (parent != null && parent is IInputElement
&& !((IInputElement)parent).Focusable)
{
parent = (FrameworkElement)parent.Parent;
}
DependencyObject scope = FocusManager.GetFocusScope(ctrl); //can pass in ctrl here because FrameworkElement inherits from DependencyObject
FocusManager.SetFocusedElement(scope, parent as IInputElement);
This works because all controls inherit from FrameworkElement which inherits from DependencyObject. So you can set ctrlto any type of control you want: ComboBox, TextBox, Button, Canvas, etc.
这是有效的,因为所有控件都从继承自 DependencyObject 的 FrameworkElement 继承而来。所以,你可以设置ctrl到任何类型的控件你想:ComboBox,TextBox,Button,Canvas,等。
回答by Anatoliy Nikolaev
Yes, there is such a possibility, in such cases, implement attachedbehavior. Logic at work with a focus must fit into DependencyPropertyChangedEventhandler.
是的,有这种可能性,在这种情况下,实施attached行为。具有焦点的逻辑必须适合DependencyPropertyChangedEvent处理程序。
Here is an example for your case:
这是您的案例的示例:
XAML
XAML
<Window x:Class="RemoveFocusHelp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:this="clr-namespace:RemoveFocusHelp"
WindowStartupLocation="CenterScreen"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox Name="TestTextBox"
this:RemoveFocusBehavior.IsRemoveFocus="False"
Width="100"
Height="25"
Text="TestText" />
<Button Name="CreateFocus"
Width="100"
Height="30"
Content="Create Focus"
HorizontalAlignment="Left"
Click="CreateFocus_Click" />
<Button Name="RemoveFocus"
Focusable="False"
Width="100"
Height="30"
Content="Remove Focus"
HorizontalAlignment="Right"
Click="RemoveFocus_Click" />
</Grid>
</Window>
Code-behind
Code-behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void CreateFocus_Click(object sender, RoutedEventArgs e)
{
TestTextBox.Focus();
}
private void RemoveFocus_Click(object sender, RoutedEventArgs e)
{
RemoveFocusBehavior.SetIsRemoveFocus(TestTextBox, true);
}
}
public class RemoveFocusBehavior
{
#region IsRemoveFocus Dependency Property
public static readonly DependencyProperty IsRemoveFocusProperty;
public static void SetIsRemoveFocus(DependencyObject DepObject, bool value)
{
DepObject.SetValue(IsRemoveFocusProperty, value);
}
public static bool GetIsRemoveFocus(DependencyObject DepObject)
{
return (bool)DepObject.GetValue(IsRemoveFocusProperty);
}
static RemoveFocusBehavior()
{
IsRemoveFocusProperty = DependencyProperty.RegisterAttached("IsRemoveFocus",
typeof(bool),
typeof(RemoveFocusBehavior),
new UIPropertyMetadata(false, IsRemoveFocusTurn));
}
#endregion
#region IsRemoveFocus Property Metadata
private static void IsRemoveFocusTurn(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
Control control = sender as Control;
if (control == null)
{
return;
}
if (e.NewValue is bool && ((bool)e.NewValue) == true)
{
FrameworkElement parent = (FrameworkElement)control.Parent;
while (parent != null && parent is IInputElement
&& !((IInputElement)parent).Focusable)
{
parent = (FrameworkElement)parent.Parent;
}
DependencyObject scope = FocusManager.GetFocusScope(control);
FocusManager.SetFocusedElement(scope, parent as IInputElement);
}
}
#endregion
}
Project is available at this
link.
项目在此可用
link。

