在 Caliburn Micro 中单击背景时,文本框是否有失去焦点的方法?
Is there a way a TextBox loses focus when clicking on the background in Caliburn Micro?
在尝试重建 WPF 应用程序以使用 Caliburn Micro 时,我发现当您在 TextBox
外部单击时它不会失去焦点。是否有针对该行为的修复方法?
我正在使用 Caliburn Micro 3.2.0。我尝试使用旧版本,但这个问题仍然存在。
XAML:
<Window x:Class="WPFUI.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFUI.Views"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
Title="ShellView" Height="450" Width="800">
<Grid>
...
<WrapPanel>
<TextBox x:Name="Name" MinWidth="50"
cal:Message.Attach="[Event LostFocus] = [Action Name_LostFocus()];
[Event PreviewTextInput] = [Action Name_PreviewTextInput($source, $eventArgs)]">
</TextBox>
...
</WrapPanel>
...
</Grid>
</Window>
我假设在 Window 中除了文本框之外没有任何其他元素,这就是它不能失去焦点的原因。实现此目的的一种方法是使 Window 可聚焦并使用行为将焦点设置到它。
例如,假设您的Xaml如下
<Window x:Class="CM.WPFApp2019.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CM.WPFApp2019.Views"
xmlns:i = "http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behaviors="clr-namespace:CM.WPFApp2019.ViewModels"
mc:Ignorable="d" Focusable="True"
Title="ShellView" Height="450" Width="800">
<i:Interaction.Behaviors>
<behaviors:ClearFocusOnClickBehavior ElementToClearFocus="{Binding ElementName=Name}"/>
</i:Interaction.Behaviors>
<Grid>
<WrapPanel>
<TextBox x:Name="Name" MinWidth="50" Focusable="True"
cal:Message.Attach="[Event LostFocus] = [Action Name_LostFocus()];
[Event PreviewTextInput] = [Action Name_PreviewTextInput($source, $eventArgs)]">
</TextBox>
</WrapPanel>
</Grid>
</Window>
请注意,我在 Window 中添加了一个名为 ClearFocusOnClickBehavior
的行为。此外,您已将 Window 的 Focusable 属性 设置为 true。
现在您可以按如下方式定义行为
public class ClearFocusOnClickBehavior : Behavior<FrameworkElement>
{
public static readonly DependencyProperty ElementToClearFocusProperty = DependencyProperty.RegisterAttached("ElementToClearFocus", typeof(FrameworkElement),
typeof(ClearFocusOnClickBehavior), new UIPropertyMetadata());
public FrameworkElement ElementToClearFocus
{
get { return (FrameworkElement)GetValue(ElementToClearFocusProperty); }
set { SetValue(ElementToClearFocusProperty, value); }
}
protected override void OnAttached()
{
AssociatedObject.MouseDown += (sender, args) =>
{
FrameworkElement ctrl = ElementToClearFocus;
FrameworkElement parent = (FrameworkElement)ElementToClearFocus.Parent;
while (parent != null && parent is IInputElement
&& !((IInputElement)parent).Focusable)
{
parent = (FrameworkElement)parent.Parent;
}
DependencyObject scope = FocusManager.GetFocusScope(ElementToClearFocus);
FocusManager.SetFocusedElement(scope, parent as IInputElement);
};
base.OnAttached();
}
}
行为会为关联的对象添加一个 MouseDown
事件,您可以在其中跟踪可以聚焦的 ElementToClearFocus
控件的 Parent
。在这种情况下,由于您已将 Window 设置为可聚焦,因此它会获得焦点。 Textbox
依次失去焦点并引发 Name_LostFocus
方法
在尝试重建 WPF 应用程序以使用 Caliburn Micro 时,我发现当您在 TextBox
外部单击时它不会失去焦点。是否有针对该行为的修复方法?
我正在使用 Caliburn Micro 3.2.0。我尝试使用旧版本,但这个问题仍然存在。
XAML:
<Window x:Class="WPFUI.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFUI.Views"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
Title="ShellView" Height="450" Width="800">
<Grid>
...
<WrapPanel>
<TextBox x:Name="Name" MinWidth="50"
cal:Message.Attach="[Event LostFocus] = [Action Name_LostFocus()];
[Event PreviewTextInput] = [Action Name_PreviewTextInput($source, $eventArgs)]">
</TextBox>
...
</WrapPanel>
...
</Grid>
</Window>
我假设在 Window 中除了文本框之外没有任何其他元素,这就是它不能失去焦点的原因。实现此目的的一种方法是使 Window 可聚焦并使用行为将焦点设置到它。
例如,假设您的Xaml如下
<Window x:Class="CM.WPFApp2019.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CM.WPFApp2019.Views"
xmlns:i = "http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behaviors="clr-namespace:CM.WPFApp2019.ViewModels"
mc:Ignorable="d" Focusable="True"
Title="ShellView" Height="450" Width="800">
<i:Interaction.Behaviors>
<behaviors:ClearFocusOnClickBehavior ElementToClearFocus="{Binding ElementName=Name}"/>
</i:Interaction.Behaviors>
<Grid>
<WrapPanel>
<TextBox x:Name="Name" MinWidth="50" Focusable="True"
cal:Message.Attach="[Event LostFocus] = [Action Name_LostFocus()];
[Event PreviewTextInput] = [Action Name_PreviewTextInput($source, $eventArgs)]">
</TextBox>
</WrapPanel>
</Grid>
</Window>
请注意,我在 Window 中添加了一个名为 ClearFocusOnClickBehavior
的行为。此外,您已将 Window 的 Focusable 属性 设置为 true。
现在您可以按如下方式定义行为
public class ClearFocusOnClickBehavior : Behavior<FrameworkElement>
{
public static readonly DependencyProperty ElementToClearFocusProperty = DependencyProperty.RegisterAttached("ElementToClearFocus", typeof(FrameworkElement),
typeof(ClearFocusOnClickBehavior), new UIPropertyMetadata());
public FrameworkElement ElementToClearFocus
{
get { return (FrameworkElement)GetValue(ElementToClearFocusProperty); }
set { SetValue(ElementToClearFocusProperty, value); }
}
protected override void OnAttached()
{
AssociatedObject.MouseDown += (sender, args) =>
{
FrameworkElement ctrl = ElementToClearFocus;
FrameworkElement parent = (FrameworkElement)ElementToClearFocus.Parent;
while (parent != null && parent is IInputElement
&& !((IInputElement)parent).Focusable)
{
parent = (FrameworkElement)parent.Parent;
}
DependencyObject scope = FocusManager.GetFocusScope(ElementToClearFocus);
FocusManager.SetFocusedElement(scope, parent as IInputElement);
};
base.OnAttached();
}
}
行为会为关联的对象添加一个 MouseDown
事件,您可以在其中跟踪可以聚焦的 ElementToClearFocus
控件的 Parent
。在这种情况下,由于您已将 Window 设置为可聚焦,因此它会获得焦点。 Textbox
依次失去焦点并引发 Name_LostFocus
方法