【问题标题】:Hide mouse cursor and StackPanel after an idle time Windows 8.1 - Universal App空闲时间后隐藏鼠标光标和 StackPanel Windows 8.1 - 通用应用程序
【发布时间】:2015-01-01 03:33:51
【问题描述】:

我正在使用 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 来说是相同的,只是控件几乎相同。

【问题讨论】:

    标签: c# xaml windows-runtime windows-8.1 win-universal-app


    【解决方案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 的输入/输出设置动画。首先,您需要在页面的 xaml 中定义两个 Storyboards。

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

    【讨论】:

    • 代码完美运行,非常感谢@Justin XL 你能告诉我一些关于动画的建议吗?非常感谢
    • MyControlsStackPanel 的名称。我以为你用的是这个名字?
    • 好的,我知道问题出在哪里了。您需要为您的StackPanel 定义RenderTransform,如下所示 - 。 ..
    • 是的,我的意思是这个异常:在 DancingUniversal.Windows.exe 中发生了“System.Exception”类型的异常,但未在用户代码中处理 WinRT 信息:无法解析 TargetProperty (UIElement.RenderTransform)。 (CompositeTransform.ScaleX) 在指定对象上。附加信息:未检测到已安装的组件。 imagizer.imageshack.com/img673/9158/VSgT4X.png
    • 太好了,你甚至在我问之前就知道我的错误了 :)) 像魅力一样工作,再次感谢 :))
    猜你喜欢
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多