WPF 不活动和活动 [英] WPF inactivity and activity

查看:17
本文介绍了WPF 不活动和活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试处理 WPF 应用程序中的用户不活动和活动,以淡入淡出一些内容.经过大量研究,我决定采用(至少在我看来)Hans Passant 发布的非常优雅的解决方案 此处.

I'm trying to handle user inactivity and activity in a WPF application to fade some stuff in and out. After a lot of research, I decided to go with the (at least in my opinion) very elegant solution Hans Passant posted here.

只有一个缺点:只要光标停留在窗口顶部,PreProcessInput 事件被连续触发.我有一个全屏应用程序,所以这会杀死它.任何我可以绕过这种行为的想法将不胜感激.

There's only one downside: As long as the cursor stays on top of the window, the PreProcessInput event gets continously fired. I'm having a full-screen application, so this kills it. Any ideas how I can bypass this behaviour would be most appreciated.

public partial class MainWindow : Window
{
    readonly DispatcherTimer activityTimer;

    public MainWindow()
    {
        InitializeComponent();

        InputManager.Current.PreProcessInput += Activity;

        activityTimer = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(10),
            IsEnabled = true
        };
        activityTimer.Tick += Inactivity;
    }

    void Inactivity(object sender, EventArgs e)
    {
        rectangle1.Visibility = Visibility.Hidden; // Update
        // Console.WriteLine("INACTIVE " + DateTime.Now.Ticks);
    }

    void Activity(object sender, PreProcessInputEventArgs e)
    {
        rectangle1.Visibility = Visibility.Visible; // Update
        // Console.WriteLine("ACTIVE " + DateTime.Now.Ticks);

        activityTimer.Stop();
        activityTimer.Start();
    }
}

更新

我可以更好地缩小所描述的行为的范围(请参阅上述代码中的 rectangle1.Visibility 更新).只要光标停留在窗口顶部并且例如控件的 Visibility 发生更改,就会引发 PreProcessInput.也许我误解了 PreProcessInput 事件的目的以及它何时触发.MSDN 在这里不是很有帮助.

I could narrow down the described behaviour better (see the rectangle1.Visibility update in the above code). As long as the cursor rests on top of the window and for example the Visibility of a control is changed, the PreProcessInput is raised. Maybe I'm misunderstanding the purpose of the PreProcessInput event and when it fires. MSDN wasn't very helpful here.

推荐答案

我可以弄清楚是什么导致了所描述的行为.

I could figure out what caused the described behaviour.

例如,当控件的 Visibility 更改时,PreProcessInput 事件由 InputReportEventArgs 类型的 PreProcessInputEventArgs.StagingItem.Input 引发.

For example when the Visibility of a control is changed, the PreProcessInput event is raised with PreProcessInputEventArgs.StagingItem.Input of the type InputReportEventArgs.

可以通过过滤 OnActivity 事件中的 MouseEventArgsKeyboardEventArgs 类型的 InputEventArgs 来避免该行为并验证是否没有按下鼠标按钮并且光标的位置仍然与应用程序处于非活动状态时相同.

The behaviour can be avoided by filtering the InputEventArgs for the types MouseEventArgs and KeyboardEventArgs in the OnActivity event and to verify if no mouse button is pressed and the position of the cursor is still the same as the application became inactive.

public partial class MainWindow : Window
{
    private readonly DispatcherTimer _activityTimer;
    private Point _inactiveMousePosition = new Point(0, 0);

    public MainWindow()
    {
        InitializeComponent();

        InputManager.Current.PreProcessInput += OnActivity;
        _activityTimer = new DispatcherTimer { Interval = TimeSpan.FromMinutes(5), IsEnabled = true };
        _activityTimer.Tick += OnInactivity;
    }

    void OnInactivity(object sender, EventArgs e)
    {
        // remember mouse position
        _inactiveMousePosition = Mouse.GetPosition(MainGrid);

        // set UI on inactivity
        rectangle.Visibility = Visibility.Hidden;
    }

    void OnActivity(object sender, PreProcessInputEventArgs e)
    {
        InputEventArgs inputEventArgs = e.StagingItem.Input;

        if (inputEventArgs is MouseEventArgs || inputEventArgs is KeyboardEventArgs)
        {
            if (e.StagingItem.Input is MouseEventArgs)
            {
                MouseEventArgs mouseEventArgs = (MouseEventArgs)e.StagingItem.Input;

                // no button is pressed and the position is still the same as the application became inactive
                if (mouseEventArgs.LeftButton == MouseButtonState.Released &&
                    mouseEventArgs.RightButton == MouseButtonState.Released &&
                    mouseEventArgs.MiddleButton == MouseButtonState.Released &&
                    mouseEventArgs.XButton1 == MouseButtonState.Released &&
                    mouseEventArgs.XButton2 == MouseButtonState.Released &&
                    _inactiveMousePosition == mouseEventArgs.GetPosition(MainGrid))
                    return;
            }

            // set UI on activity
            rectangle.Visibility = Visibility.Visible;

            _activityTimer.Stop();
            _activityTimer.Start();
        }
    }
}

这篇关于WPF 不活动和活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆