我有两个控件a ToolBar和a TextBox.ToolBar有一个Button打开Popup另一个的工具栏Button.
当前行为:如果我在里面单击TextBox并且它变得聚焦,然后单击按钮从中ToolBar打开弹出窗口TextBox仍然聚焦并接收所有键盘输入.
现在我知道这是FocusScope中的项目的默认行为ToolBar,但是当弹出窗口打开时我不需要这种行为.我怎么能避免呢?
这是一个例子:
<Window x:Class="WpfApplication67.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
</Window.Resources>
<StackPanel HorizontalAlignment="Left" Width="400">
<ToolBar>
<ToggleButton Name="openButton">Open Popup</ToggleButton>
<Popup Focusable="True"
Placement="Right"
StaysOpen="False"
IsOpen="{Binding IsChecked, ElementName=openButton, Mode=TwoWay}"
PlacementTarget="{Binding ElementName=openButton}">
<StackPanel
Width="100"
Height="100"
Background="DarkGray"
Focusable="True">
<Button>More</Button>
</StackPanel>
</Popup>
</ToolBar>
<TextBox Text="Set focus on this..." />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
编辑:我正在努力寻找一个解释,关于谁将焦点移动到嵌套的FocusScope内的按钮点击,以及如何阻止一些按钮(如Popup中的那个)进行操作.
你主要有三个要求(如果错了,请纠正我):
让我们逐一挑选这些要求.
如果弹出窗口,焦点应该在popUp内部,即在StackPanel上.
就像我在评论中提到的那样,将重点放在Opened了PopUp事件的stackPanel上:
private void Popup_Opened(object sender, EventArgs e)
{
stackPanel.Focus();
}
Run Code Online (Sandbox Code Playgroud)
在popUp关闭时,焦点应该保留回textBox.
挂钩关闭事件并将焦点放回TextBox:
private void Popup_Closed(object sender, EventArgs e)
{
textBox.Focus();
}
Run Code Online (Sandbox Code Playgroud)
单击popUp中的按钮时,焦点不应该离开popUp.
现在,是棘手的部分.正如您在popUp中单击按钮时在评论中所提到的,焦点移动到PopUp之外.
你可以做的阻止是将处理程序附加到PreviewLostKeyboardFocusstackPanel的事件.如果keyBoard焦点位于popUp中,则e.Handled = true在处理程序中检查条件,设置为仅在此处处理事件并且不会引发气泡事件,这将强制键盘焦点位于stackPanel之外.
如果你在stackPanel besies按钮内有另一个TextBox,那么处理事件也不允许你在popUp中移动焦点.为了避免这种情况,您可以检查新的焦点元素是否不属于stackPanel,然后只处理该事件.
这是实现它的代码(在StackPanel的PreviewLostKeyboardFocus事件上添加处理程序):
private void stackPanel_PreviewLostKeyboardFocus(object sender,
KeyboardFocusChangedEventArgs e)
{
var newFocusedChild = e.NewFocus as FrameworkElement;
bool isMovingWithinPanel = newFocusedChild != null
&& newFocusedChild.Parent == stackPanel;
// If keyboard focus is within stackPanel and new focused element is
// outside of stackPanel boundaries then only handle the event.
if (stackPanel.IsKeyboardFocusWithin && !isMovingWithinPanel)
e.Handled = true;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4286 次 |
| 最近记录: |