簡體   English   中英

當子控件具有輸入焦點時,為什么鍵盤輸入不適用於 ScrollViewer?

[英]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時沒有鍵盤導航的類似問題。 添加FocusableIsTabStop解決了我的問題。

<ScrollViewer
    Focusable="True"
    IsTabStop="True">
    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
 </ScrollViewer>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM