WPF活动和活动WPF

2023-09-02 10:30:25 作者:我拿青春賭明天

我想处理在WPF应用程序用户的活动和行为淡化一些东西进出。大量的研究后,我决定去与(至少在我看来),很优雅的解决方案汉斯帕桑特发布here.

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.

只有一个缺点:只要光标停留在窗口的顶部,在$p$pProcessInput事件被continously解雇。我有一个全屏幕应用程序,所以这个杀死它。任何想法如何,我可以绕过这个问题将是最AP preciated。

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();
    }
}

更新

我可以缩小描述的行为更好的(见上面code中的 rectangle1.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.

例如,当能见度控件的改变时,$p$pProcessInput事件引发与 preProcessInputEventArgs.StagingItem.Input 类型 InputReportEventArgs

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

的行为,可避免过滤 InputEventArgs 的类型 MouseEventArgs KeyboardEventArgs OnActivity 事件,并核实,如果没有鼠标按键时pssed $ P $和光标的位置仍然是作为应用程序成为同无效。

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();
        }
    }
}