空闲时间后隐藏鼠标光标和 StackPanel Windows 8.1 - 通用应用程序
Hide mouse cursor and StackPanel after an idle time Windows 8.1 - Universal App
我正在使用 C# 和 XAML 编写一个视频播放器应用程序,一个通用应用程序(Windows 8.1 和 Windows Phone 8.1)。有一个非常好的用户体验是:
- 当鼠标在一段时间后空闲时,鼠标和所有控件(播放、暂停..)都被隐藏
- 当鼠标移动时,出现鼠标光标和所有控件。
它看起来与 Windows 8.1 上的视频应用一模一样;虽然简单,但它的用户体验非常好。
这是我的一些控件,我将它们全部放在 Stackpanel 中:
<StackPanel x:Name="MyControls"
Orientation="Horizontal" >
<Button x:Name="btnPlay"
Click="btnPlay_Click" />
<Button x:Name="btnPause"
Click="btnPause_Click" />
</StackPanel>
还有我的控件隐藏代码:
private void btnPlay_Click(object sender, RoutedEventArgs e)
{
videoMediaElement.Play();
}
private void btnPause_Click(object sender, RoutedEventArgs e)
{
videoMediaElement.Pause();
}
那么,我的问题是如何做到这一点?
- 当鼠标在一段时间后空闲时,鼠标和所有控件(播放、暂停..)都被隐藏
- 当鼠标移动时,出现鼠标光标和所有控件。
因为它是一个通用应用程序,所以我想 Windows Phone 8.1 的解决方案是相同的,只是几乎相同的控件。
如何创建一个 DispatcherTimer
以在一定时间后隐藏 StackPanel
和光标并在指针移动时显示它们?
private DispatcherTimer _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(5) };
public MainPage()
{
this.InitializeComponent();
}
private void MainPage_PointerMoved(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
this.ShowControls();
// restart the timer whenever the user moves the cursor
_timer.Start();
}
private void Timer_Tick(object sender, object e)
{
this.HideControls();
}
private void btnPlay_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
_timer.Tick += Timer_Tick;
this.PointerMoved += MainPage_PointerMoved;
_timer.Start();
}
private void btnPause_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
_timer.Tick -= Timer_Tick;
this.PointerMoved -= MainPage_PointerMoved;
_timer.Stop();
}
private void HideControls()
{
// todo: better use animation here
this.MyControls.Visibility = Visibility.Collapsed;
Window.Current.CoreWindow.PointerCursor = null;
}
private void ShowControls()
{
// todo: better use animation here
this.MyControls.Visibility = Visibility.Visible;
Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 1);
}
奖金
说如果你想为 StackPanel
的 in/out 设置动画。首先你需要在页面的 xaml.
中定义两个 Storyboard
<Page.Resources>
<Storyboard x:Name="HideAnimation">
<DoubleAnimation Duration="0:0:0.3" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="MyControls" d:IsOptimized="True"/>
<DoubleAnimation Duration="0:0:0.3" To="0.6" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="MyControls" d:IsOptimized="True">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseIn"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Duration="0:0:0.3" To="0.6" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="MyControls" d:IsOptimized="True">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseIn"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsHitTestVisible)" Storyboard.TargetName="MyControls">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<x:Boolean>False</x:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.3">
<DiscreteObjectKeyFrame.Value>
<x:Boolean>True</x:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="ShowAnimation">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="MyControls">
<SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimation Duration="0:0:0.3" To="1" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="MyControls" d:IsOptimized="True">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Duration="0:0:0.3" To="1" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="MyControls" d:IsOptimized="True">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsHitTestVisible)" Storyboard.TargetName="MyControls">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<x:Boolean>True</x:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.3">
<DiscreteObjectKeyFrame.Value>
<x:Boolean>True</x:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
然后您只需调用它们而不是设置 Visibility
。
private void HideControls()
{
this.HideAnimation.Begin();
Window.Current.CoreWindow.PointerCursor = null;
}
private void ShowControls()
{
this.ShowAnimation.Begin();
Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 1);
}
我正在使用 C# 和 XAML 编写一个视频播放器应用程序,一个通用应用程序(Windows 8.1 和 Windows Phone 8.1)。有一个非常好的用户体验是:
- 当鼠标在一段时间后空闲时,鼠标和所有控件(播放、暂停..)都被隐藏
- 当鼠标移动时,出现鼠标光标和所有控件。
它看起来与 Windows 8.1 上的视频应用一模一样;虽然简单,但它的用户体验非常好。
这是我的一些控件,我将它们全部放在 Stackpanel 中:
<StackPanel x:Name="MyControls"
Orientation="Horizontal" >
<Button x:Name="btnPlay"
Click="btnPlay_Click" />
<Button x:Name="btnPause"
Click="btnPause_Click" />
</StackPanel>
还有我的控件隐藏代码:
private void btnPlay_Click(object sender, RoutedEventArgs e)
{
videoMediaElement.Play();
}
private void btnPause_Click(object sender, RoutedEventArgs e)
{
videoMediaElement.Pause();
}
那么,我的问题是如何做到这一点?
- 当鼠标在一段时间后空闲时,鼠标和所有控件(播放、暂停..)都被隐藏
- 当鼠标移动时,出现鼠标光标和所有控件。
因为它是一个通用应用程序,所以我想 Windows Phone 8.1 的解决方案是相同的,只是几乎相同的控件。
如何创建一个 DispatcherTimer
以在一定时间后隐藏 StackPanel
和光标并在指针移动时显示它们?
private DispatcherTimer _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(5) };
public MainPage()
{
this.InitializeComponent();
}
private void MainPage_PointerMoved(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
this.ShowControls();
// restart the timer whenever the user moves the cursor
_timer.Start();
}
private void Timer_Tick(object sender, object e)
{
this.HideControls();
}
private void btnPlay_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
_timer.Tick += Timer_Tick;
this.PointerMoved += MainPage_PointerMoved;
_timer.Start();
}
private void btnPause_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
_timer.Tick -= Timer_Tick;
this.PointerMoved -= MainPage_PointerMoved;
_timer.Stop();
}
private void HideControls()
{
// todo: better use animation here
this.MyControls.Visibility = Visibility.Collapsed;
Window.Current.CoreWindow.PointerCursor = null;
}
private void ShowControls()
{
// todo: better use animation here
this.MyControls.Visibility = Visibility.Visible;
Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 1);
}
奖金
说如果你想为 StackPanel
的 in/out 设置动画。首先你需要在页面的 xaml.
Storyboard
<Page.Resources>
<Storyboard x:Name="HideAnimation">
<DoubleAnimation Duration="0:0:0.3" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="MyControls" d:IsOptimized="True"/>
<DoubleAnimation Duration="0:0:0.3" To="0.6" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="MyControls" d:IsOptimized="True">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseIn"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Duration="0:0:0.3" To="0.6" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="MyControls" d:IsOptimized="True">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseIn"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsHitTestVisible)" Storyboard.TargetName="MyControls">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<x:Boolean>False</x:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.3">
<DiscreteObjectKeyFrame.Value>
<x:Boolean>True</x:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="ShowAnimation">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="MyControls">
<SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimation Duration="0:0:0.3" To="1" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="MyControls" d:IsOptimized="True">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Duration="0:0:0.3" To="1" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="MyControls" d:IsOptimized="True">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsHitTestVisible)" Storyboard.TargetName="MyControls">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<x:Boolean>True</x:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.3">
<DiscreteObjectKeyFrame.Value>
<x:Boolean>True</x:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
然后您只需调用它们而不是设置 Visibility
。
private void HideControls()
{
this.HideAnimation.Begin();
Window.Current.CoreWindow.PointerCursor = null;
}
private void ShowControls()
{
this.ShowAnimation.Begin();
Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 1);
}