You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI中如何监听全局键盘事件?ListView排序时判断CTRL键状态

Solution

1. 修复全局键盘事件注册问题

构造函数中Window.Current为null,是因为此时页面还未绑定到窗口。需将事件绑定移至页面生命周期的后续阶段(如OnNavigatedTo)或控件的Loaded事件中,此时窗口引用已确定存在。

2. 全局跟踪CTRL键状态

维护一个布尔变量记录CTRL键是否被按下,通过KeyDown和KeyUp事件同步更新该状态,确保点击表头时能准确获取按键状态。

3. 集成ListView排序逻辑

在表头点击触发排序时,检查CTRL键状态变量,决定是扩展现有排序规则还是仅按当前列排序。


完整代码示例

public sealed partial class PositionView : Page
{
    private bool _isCtrlPressed;
    private readonly PositionViewModel _viewModel;

    public PositionView(PositionViewModel positionViewModel)
    {
        _viewModel = positionViewModel;
        DataContext = _viewModel;
        InitializeComponent();
        // 若为UserControl,可绑定Loaded事件替代OnNavigatedTo
        Loaded += PositionView_Loaded;
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        // 页面导航完成后注册全局键盘事件
        Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
        Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp;
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        base.OnNavigatedFrom(e);
        // 页面离开时注销事件,避免内存泄漏
        Window.Current.CoreWindow.KeyDown -= CoreWindow_KeyDown;
        Window.Current.CoreWindow.KeyUp -= CoreWindow_KeyUp;
    }

    private void PositionView_Loaded(object sender, RoutedEventArgs e)
    {
        // UserControl场景下的事件注册
        Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
        Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp;
    }

    private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
    {
        if (args.VirtualKey == Windows.System.VirtualKey.Control)
        {
            _isCtrlPressed = true;
        }
    }

    private void CoreWindow_KeyUp(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
    {
        if (args.VirtualKey == Windows.System.VirtualKey.Control)
        {
            _isCtrlPressed = false;
        }
    }

    // ListView表头点击事件处理
    private void ListViewHeader_Click(object sender, RoutedEventArgs e)
    {
        var clickedColumn = (sender as FrameworkElement)?.Tag as string;
        if (string.IsNullOrEmpty(clickedColumn)) return;

        if (_isCtrlPressed)
        {
            // 扩展排序列表
            _viewModel.ExtendSort(clickedColumn);
        }
        else
        {
            // 仅按当前列排序
            _viewModel.SetSingleSort(clickedColumn);
        }
    }
}

关键说明

  • 事件清理: 页面/控件卸载时必须注销键盘事件,防止内存泄漏。
  • 状态准确性: 同时监听KeyDown和KeyUp事件,确保即使CTRL键在页面加载前被按下,状态也能正确更新。
  • 排序逻辑: ExtendSort和SetSingleSort为ViewModel中的占位方法,需根据实际业务逻辑实现排序规则的扩展与重置。

内容的提问来源于stack exchange,提问作者user365462

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 07:35:17