在XAML/C#(Windows 10)中防止ListView的Return(Enter)、上箭头和下箭头键的默认行为

3
当一个列表视图获得焦点时,按下回车键的默认行为是选择列表视图的第一个元素,上下箭头键滚动列表视图。我正在尝试阻止这种默认行为并连接我的自定义逻辑。
我能够使用KeyDown实现列表视图的访问键,如下所示:
代码后台方法:
CoreWindow.GetForCurrentThread().KeyDown += KeyDownHandler;

MVVM模式:

<ListView SelectedIndex="{Binding IsSelected, Mode=TwoWay}"/>

触发 Keydown 属性:

<core:EventTriggerBehavior EventName="KeyDown">
        <core:InvokeCommandAction Command="{x:Bind VMDataContext.KeyDownCommand}" />
    </core:EventTriggerBehavior>

使用行为将列表视图的滚动条滚动到所选索引:

<corebehaviors:ListViewScrollBehaviour SelectedIndex="{x:Bind IsSelected, Mode=OneWay}"/>

当列表视图没有焦点时,上述处理程序将被触发。当列表视图具有焦点时,箭头向上、向下和回车键的默认行为将被触发,而不是我的附加行为。是否有一种方法可以防止默认行为?

3个回答

5
考虑扩展 ListView 控件并重写 OnKeyDown 处理程序。
public class ExtendedListView : ListView
{
    protected override void OnKeyDown(KeyRoutedEventArgs e)
    {
        if (e.Key == VirtualKey.Enter || e.Key == VirtualKey.Up || e.Key == VirtualKey.Down)
        {
            return;
        }

        base.OnKeyDown(e);
    }
}

谢谢Justin!这对于回车键非常完美,但不适用于上下箭头。奇怪的是,断点没有被触发上下箭头键。我还尝试重写OnKeyUp函数并观察到相同的行为。 - Amar Zeno
顺便提一下,在某些情况下,您可能希望调用 e.Handled = true; 而不是 return - Justin XL

1
尝试这个。
CoreWindow.GetForCurrentThread().KeyDown += new KeyEventHandler(ListView_KeyDown);

private void ListView_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
        //do ur stuff
}

最好使用PreviewKeyDown事件而不是KeyDown事件。

ListView_KeyDown(CoreWindow sender, KeyEventArgs args) 只能接受 CoreWindow 和 KeyEventArgs 两个参数。我也无法使用 PreviewKeyDown。不确定 WinRT 应用程序是否支持该功能。 - Amar Zeno

1

回车键是所谓的虚拟键(点击链接查看MSDN文档)。这应该可以解决问题:

        private void UIElement_OnKeyDown(object sender, KeyRoutedEventArgs e)
        {
            if (e.Key == VirtualKey.Enter)
            {

            }
        }

希望这有所帮助。

如上所述,当按下Enter键时,ListView的此keydown事件不会触发输入。相反,它将打开ListView的第一项。 - Amar Zeno
ListView 的 Enter 键默认行为是否可以被覆盖? - Amar Zeno
我猜你的意思是选择第一个项目,然后打开它。如果你在ListView本身上执行这个操作,它应该可以导航到另一个页面。但是,你必须考虑到,如果没有预先选择任何项目(例如使用箭头键),它将始终进入第一个项目。如果选择了其他项目,则应该使用该项目。 - MSicc
有没有办法防止“默认打开”行为发生,使得即使我按下回车键,也不会发生任何事情。这样我就可以将自定义逻辑附加到它上面了。 - Amar Zeno
通常情况下,只需添加您的代码就可以了。如果不行,更详细的查看你的ListView XAML将有助于确定此行为的原因。 - MSicc
我想知道你的自定义逻辑与默认行为有何不同(因为用户已经习惯了默认行为,所以默认行为是好的)。实现你的目标的唯一方法是创建一个派生自标准ListView的自己的ListView,并覆盖处理它的事件。 - MSicc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接