C# 一段视频反复出现空闲事件,并恢复到上一个窗口上检测到的用户活动
我对WPF有一个要求,即在空闲事件上反复播放视频,并在检测到用户活动时恢复到上一个窗口 为此,我遵循了马丁·布伯的回答 在XAML中,我有VideoGrid和WindowGrid,通过检测空闲事件,我改变了彼此的可见性 以下是用于说明所述问题的源代码 假设空闲事件发生在5秒。当您单击按钮时,空闲事件在10秒时发生 它工作得非常好,除了 对于按钮单击的第一个空闲事件,VideoGrid尝试显示,但无法显示(它只是闪烁),然后下一个空闲事件都正常工作 我们感谢您的反馈和建议,以消除眨眼问题C# 一段视频反复出现空闲事件,并恢复到上一个窗口上检测到的用户活动,c#,wpf,winforms,C#,Wpf,Winforms,我对WPF有一个要求,即在空闲事件上反复播放视频,并在检测到用户活动时恢复到上一个窗口 为此,我遵循了马丁·布伯的回答 在XAML中,我有VideoGrid和WindowGrid,通过检测空闲事件,我改变了彼此的可见性 以下是用于说明所述问题的源代码 假设空闲事件发生在5秒。当您单击按钮时,空闲事件在10秒时发生 它工作得非常好,除了 对于按钮单击的第一个空闲事件,VideoGrid尝试显示,但无法显示(它只是闪烁),然后下一个空闲事件都正常工作 我们感谢您的反馈和建议,以消除眨眼问题
// set UI on inactivity
private void OnInactivity(object sender, EventArgs e)
{
_inactiveMousePosition = Mouse.GetPosition(this);
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
if (WindowGrid.Visibility == Visibility.Visible)
{
WindowGrid.Visibility = Visibility.Collapsed;
}
if (VideoGrid.Visibility == Visibility.Collapsed)
{
WindowState = WindowState.Maximized;
WindowStyle = WindowStyle.None;
//play video
videoplayer.Play();
VideoGrid.Visibility = Visibility.Visible;
}
}));
}
private void OnActivity(object sender, PreProcessInputEventArgs e)
{
var inputEventArgs = e.StagingItem.Input;
if (inputEventArgs is System.Windows.Input.MouseEventArgs || inputEventArgs is KeyboardEventArgs)
{
if (e.StagingItem.Input is System.Windows.Input.MouseEventArgs)
{
var mouseEventArgs = (System.Windows.Input.MouseEventArgs)e.StagingItem.Input;
// no button is pressed and the position is still the same as the application became inactive
if (!(
mouseEventArgs.LeftButton == MouseButtonState.Pressed ||
mouseEventArgs.RightButton == MouseButtonState.Pressed ||
mouseEventArgs.MiddleButton == MouseButtonState.Pressed ||
mouseEventArgs.XButton1 == MouseButtonState.Pressed ||
mouseEventArgs.XButton2 == MouseButtonState.Pressed
//|| _inactiveMousePosition != mouseEventArgs.GetPosition(this)
))
{
return;
}
}
// set UI on activity
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
if (VideoGrid.Visibility == Visibility.Visible)
{
WindowState = WindowState.Normal;
WindowStyle = WindowStyle.SingleBorderWindow;
//stop video
videoplayer.Stop();
VideoGrid.Visibility = Visibility.Collapsed;
}
if (WindowGrid.Visibility == Visibility.Collapsed)
{
WindowGrid.Visibility = Visibility.Visible;
}
}));
_activityTimer.Stop();
_activityTimer.Start();
}
}
通过调试您的代码,我可以给您一个答案,但可能不是一个非常令人满意的答案 我在OnActivity中为您的代码添加了一些调试输出
private async void OnInactivity(object sender, EventArgs e)
{
// remember mouse position
_inactiveMousePosition = Mouse.GetPosition(this);
// set UI on inactivity
Debug.WriteLine ( DateTime.Now.ToString("HH:mm:ss.fffffff") + " Inactivity" ) ;
await System.Windows.Application.Current.Dispatcher.InvokeAsync(new Action(() =>
{
Grid1.Visibility = Visibility.Collapsed;
videoplayer.Play();
Grid2.Visibility = Visibility.Visible;
}));
}
private async void OnActivity(object sender, PreProcessInputEventArgs e)
{
var inputEventArgs = e.StagingItem.Input;
if (inputEventArgs is System.Windows.Input.MouseEventArgs || inputEventArgs is KeyboardEventArgs)
{
if (e.StagingItem.Input is System.Windows.Input.MouseEventArgs)
{
var mouseEventArgs = (System.Windows.Input.MouseEventArgs)e.StagingItem.Input;
if (!(
mouseEventArgs.LeftButton == MouseButtonState.Pressed ||
mouseEventArgs.RightButton == MouseButtonState.Pressed ||
mouseEventArgs.MiddleButton == MouseButtonState.Pressed ||
mouseEventArgs.XButton1 == MouseButtonState.Pressed ||
mouseEventArgs.XButton2 == MouseButtonState.Pressed
|| _inactiveMousePosition != mouseEventArgs.GetPosition(this)
))
{
return;
}
}
Debug.WriteLine ( DateTime.Now.ToString("HH:mm:ss.fffffff") + " Activity " + inputEventArgs.RoutedEvent.ToString() ) ;
// set UI on activity
await System.Windows.Application.Current.Dispatcher.InvokeAsync(new Action(() =>
{
videoplayer.Stop();
Grid1.Visibility = Visibility.Visible;
Grid2.Visibility = Visibility.Hidden;
}));
_activityTimer.Stop();
_activityTimer.Start();
}
}
在活动中
private async void OnInactivity(object sender, EventArgs e)
{
// remember mouse position
_inactiveMousePosition = Mouse.GetPosition(this);
// set UI on inactivity
Debug.WriteLine ( DateTime.Now.ToString("HH:mm:ss.fffffff") + " Inactivity" ) ;
await System.Windows.Application.Current.Dispatcher.InvokeAsync(new Action(() =>
{
Grid1.Visibility = Visibility.Collapsed;
videoplayer.Play();
Grid2.Visibility = Visibility.Visible;
}));
}
private async void OnActivity(object sender, PreProcessInputEventArgs e)
{
var inputEventArgs = e.StagingItem.Input;
if (inputEventArgs is System.Windows.Input.MouseEventArgs || inputEventArgs is KeyboardEventArgs)
{
if (e.StagingItem.Input is System.Windows.Input.MouseEventArgs)
{
var mouseEventArgs = (System.Windows.Input.MouseEventArgs)e.StagingItem.Input;
if (!(
mouseEventArgs.LeftButton == MouseButtonState.Pressed ||
mouseEventArgs.RightButton == MouseButtonState.Pressed ||
mouseEventArgs.MiddleButton == MouseButtonState.Pressed ||
mouseEventArgs.XButton1 == MouseButtonState.Pressed ||
mouseEventArgs.XButton2 == MouseButtonState.Pressed
|| _inactiveMousePosition != mouseEventArgs.GetPosition(this)
))
{
return;
}
}
Debug.WriteLine ( DateTime.Now.ToString("HH:mm:ss.fffffff") + " Activity " + inputEventArgs.RoutedEvent.ToString() ) ;
// set UI on activity
await System.Windows.Application.Current.Dispatcher.InvokeAsync(new Action(() =>
{
videoplayer.Stop();
Grid1.Visibility = Visibility.Visible;
Grid2.Visibility = Visibility.Hidden;
}));
_activityTimer.Stop();
_activityTimer.Start();
}
}
以下是按下按钮后的一点输出:
23:45:31.0583181 Activity Mouse.MouseMove
23:45:31.0643177 Activity Mouse.QueryCursor
23:45:31.0653178 Activity Mouse.PreviewMouseMove
23:45:31.0663188 Activity Mouse.MouseMove
23:45:31.0723180 Activity Mouse.QueryCursor
23:45:31.0753176 Activity Mouse.PreviewMouseMove
23:45:31.0763193 Activity Mouse.MouseMove
23:45:36.0722537 Inactivity
23:45:36.0752537 Activity Keyboard.PreviewGotKeyboardFocus
23:45:36.0782576 Activity Keyboard.PreviewKeyboardInputProviderAcquireFocus
23:45:36.0802536 Activity Keyboard.KeyboardInputProviderAcquireFocus
23:45:36.0832529 Activity Keyboard.LostKeyboardFocus
23:45:36.0842549 Activity Keyboard.GotKeyboardFocus
23:45:41.1041883 Inactivity
23:45:42.4981698 Activity Mouse.QueryCursor
23:45:42.5001740 Activity Mouse.PreviewMouseMove
23:45:42.5031736 Activity Mouse.MouseMove
23:45:42.5071741 Activity Mouse.QueryCursor
23:45:42.5091736 Activity Mouse.PreviewMouseMove
23:45:42.5111735 Activity Mouse.MouseMove
5秒不活动后,它尝试启动视频,但会立即引发一些与焦点改变相关的事件
我猜这意味着点击按钮可以使按钮获得焦点。启动视频会使其失去焦点,从而产生一些事件
我能够通过过滤掉这些事件来解决问题。这是我对OnActivity函数的修改版本,其中我按名称过滤掉了这些事件:
private async void OnActivity(object sender, PreProcessInputEventArgs e)
{
var inputEventArgs = e.StagingItem.Input;
switch ( inputEventArgs.RoutedEvent.Name )
{
case "PreviewGotKeyboardFocus":
case "PreviewKeyboardInputProviderAcquireFocus":
case "KeyboardInputProviderAcquireFocus":
case "LostKeyboardFocus":
case "GotKeyboardFocus":
return ;
}
if (inputEventArgs is System.Windows.Input.MouseEventArgs || inputEventArgs is KeyboardEventArgs)
{
if (e.StagingItem.Input is System.Windows.Input.MouseEventArgs)
{
var mouseEventArgs = (System.Windows.Input.MouseEventArgs)e.StagingItem.Input;
if (!(
mouseEventArgs.LeftButton == MouseButtonState.Pressed ||
mouseEventArgs.RightButton == MouseButtonState.Pressed ||
mouseEventArgs.MiddleButton == MouseButtonState.Pressed ||
mouseEventArgs.XButton1 == MouseButtonState.Pressed ||
mouseEventArgs.XButton2 == MouseButtonState.Pressed
|| _inactiveMousePosition != mouseEventArgs.GetPosition(this)
))
{
return;
}
}
// set UI on activity
await System.Windows.Application.Current.Dispatcher.InvokeAsync(new Action(() =>
{
videoplayer.Stop();
Grid1.Visibility = Visibility.Visible;
Grid2.Visibility = Visibility.Hidden;
}));
_activityTimer.Stop();
_activityTimer.Start();
}
}
我不知道是否还有其他事件需要过滤掉,我也不知道按事件名称过滤是否是最好的方法。是否确定VideoGrid已正确初始化(即可见性.折叠)?另外,请记住Visibility还有第三种可能的隐藏状态。谢谢,我非常确定VideoGrid已正确初始化。我不这么认为,这是一个可见性问题。如果没有按钮点击,则不会出现任何问题。它仅出现在按钮点击的第一个空闲事件上。非常感谢。这在我的解决方案中真的很有效。。我真的很感激你的回答。。你太棒了!