[英]Why doesn't keyboard input work for a ScrollViewer when the child control has input focus?
當子控件具有輸入焦點時,為什么鍵盤輸入不適用於ScrollViewer
?
這就是場景。 WPF 窗口打開。 它將焦點設置到嵌入在ScrollViewer
中的ScrollViewer
。
我敲了上下左右鍵。 ScrollViewer
似乎不處理關鍵事件,有人知道為什么嗎?
這是最簡單的例子:
<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="300" Width="300"
FocusManager.FocusedElement="{Binding ElementName=control}"
>
<Grid>
<ScrollViewer
HorizontalScrollBarVisibility="Auto"
>
<ItemsControl
x:Name="control"
Width="1000"
Height="1000"
/>
</ScrollViewer>
</Grid>
</Window>
當您啟動包含此窗口的應用程序時,“控件”似乎具有我預期的焦點。 按下該鍵似乎會導致按鍵事件冒泡到達ScrollViewer
(我使用 WPF Snoop 進行了檢查)。 我不知道為什么它不響應輸入。
問題
ScrollViewer 會忽略 OriginalSource 不是 ScrollViewer 的所有 KeyDown 事件。 KeyDown 上的 OriginalSource 設置為焦點控件,因此當孩子擁有焦點時 ScrollViewer 會忽略它。
解決方案
捕獲 KeyDown 事件並直接在 ScrollViewer 上生成它的副本,以便它具有正確的 OriginalSource,如下所示:
void ScrollViewer_KeyDown(object sender, KeyEventArgs e)
{
if(e.Handled) return;
var temporaryEventArgs =
new KeyEventArgs(e.KeyboardDevice, e.InputSource, e.Timestamp, e.Key)
{
RoutedEvent = e.RoutedEvent
};
// This line avoids it from resulting in a stackoverflowexception
if (sender is ScrollViewer) return;
((ScrollViewer)sender).RaiseEvent(temporaryEventArgs);
e.Handled = temporaryEventArgs.Handled;
}
可以在 XAML 中添加事件處理程序:
<ScrollViewer KeyDown="ScrollViewer_KeyDown" />
或在代碼中:
scrollViewer.AddHandler(Keyboard.KeyDownEvent, ScrollViewer_KeyDown);
如果 ScrollViewer 位於某個模板內並且您有代碼可以找到它,則后者更適用。
為了讓 ScrollViewer 對您的鍵盤鍵做出反應 - 它需要 IsFocused="True" - 現在它的孩子擁有焦點。
為了證明這一點 - 嘗試在您的 Loaded 事件中手動將焦點設置到 ScrollViewer(您可能必須設置 IsFocusable="True" 才能在 ScrollViewer 上工作)- 現在鍵應該可以工作了。 如果您希望它以其他方式工作,則需要在 ScrollViewer(KeyDown/KeyPress 等)上設置適當的 EventHandlers
在ItemsControl.Template
使用ScrollViewer
時沒有鍵盤導航的類似問題。 添加Focusable
和IsTabStop
解決了我的問題。
<ScrollViewer
Focusable="True"
IsTabStop="True">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.