UWP – 按空格时不要点击事件(如电影和电视应用程序)
我正在制作自定义媒体播放器,并尝试重现与电影和电视应用(Windows 10 CU)相同的行为。
无论如何, 空间都用于播放和暂停video。 在聚焦时, 空格 不用于单击按钮(但输入是)。 这种行为打破了一些关于键盘可访问性的规则,但我认为没关系。 用于播放和暂停的空间是用户期望的。
问题是:他们是怎么做到的?
我发现了一些半解决方案:
解决方案1 Window.Current.CoreWindow.KeyDown
以及if
Click Event Handler
Page.xaml.cs:
protected override void OnNavigatedTo(NavigationEventArgs e) { Window.Current.CoreWindow.KeyDown += CoreWindowOnKeyDown; //... } bool isItSpace; private void CoreWindowOnKeyDown(CoreWindow sender, KeyEventArgs args) { if (args.VirtualKey == VirtualKey.Space) isItSpace = true; } private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { if (isItSpace) { isItSpace = false; return; } //... }
Page.xaml:
为什么不:
- 需要在每个Click Handler中添加
if
- 有按钮点击动画……
解决方案2在Window.Current.CoreWindow.KeyDown
禁用焦点按钮并在KeyUp
启用它
就像是:
if (FocusManager.GetFocusedElement() is Button) { var bu = (Button)FocusManager.GetFocusedElement(); bu.IsEnabled = false; }
为什么不
- 它从禁用按钮更改焦点。 启用后需要将其更改回来。 重点是跳..
- 出现禁用和启用动画
- 太hackie了
解决方案3 button.ClickMode = ClickMode.Hover
当ClickMode
设置为“ Hover
,无法使用键盘单击它。 当我在Window的KeyDown
处理程序中更改它时(如解决方案2),它仍然第一次冒泡到Click事件。 解决方案可以将所有按钮设置为Hover
,但在这种情况下, Enter不会导致Click,我需要更改所有按钮…
你有什么更好的解决方案吗?
这个问题归结为,当您单击媒体命令栏中的按钮时,它会自动聚焦 ,而Enter键或空格键等键将自动触发按钮的操作。
因此,要解决此问题,您只需要找到一种方法来从中删除自动对焦。
在Windows 10 build 14393之前,您可以尝试在单击后手动将焦点设置为其他元素,但这对我来说就像是一个黑客。
在1 4393年 ,他们引入了一个名为AllowFocusOnInteraction
的新属性,它可以在这种特殊情况下帮助你。 基本上,这样做的目的是在用户与控件交互后不自动聚焦控件,因此焦点将保留在当前聚焦的元素上。
要应用此function,您需要获取MediaTransportControls控件的默认样式,您可以在其中访问所有媒体命令栏按钮。
然后你只需将AllowFocusOnInteraction="False"
附加到除PlayPauseButton
之外的所有AppBarButton
(不要忘记Flyout
的按钮,如AudioMuteButton
!)。
我甚至会更进一步,在最初加载页面时手动将焦点设置在PlayPauseButton
上。 因此,每当按下 Space键时,您将在此按钮上看到一个很好的按下视觉,以指示已调用播放/暂停操作。
另请注意,这样做不会影响键盘导航。 如果用户想要,他仍然可以使用Tab键在按钮之间导航。 因此一般用户可访问性不受影响。
更新
我个人希望任何有针对性的按钮能够在Space键盘上做出反应,但如果你想要与官方电影和电视应用程序完全相同的视觉行为,那也是可能的。
我们不是编写大量的代码隐藏,而是创建一个封装所有逻辑的ExtendedAppBarButton
。
这个想法与您的解决方案2非常相似,我们将使用
AddHandler(KeyDownEvent, new KeyEventHandler(OnKeyDown), true); AddHandler(KeyUpEvent, new KeyEventHandler(OnKeyUp), true);
每当按下Space键时切换IsEnabled
。 此外,我们将有一个特殊的IsPlayPauseButton
依赖项属性,该属性订阅Window
的KeyDown
事件,以便在设置为True
时手动调用按钮单击。
在我们的ExtendedAppBarButton
的默认样式中,我们需要确保正确设置以下内容 –
请注意, UseSystemFocusVisuals
设置为False
,因为我们正在创建自己的焦点视觉,以避免系统出现一个您已经注意到的闪烁问题。
此外,我们将删除Disabled
状态内的Storybaord
,因为我们不希望在IsEnabled
属性更改之间发生任何动画。
最后,您需要获取MediaTransportControls
的默认样式,并将所有AppBarButton
替换为我们刚刚创建的样式。
这里有很多东西,但是一旦你完成所有设置,你就不必担心在你的媒体页面上处理所有这些了。
我已经在这里创建了一个简单的演示项目,以防任何事情都不清楚。 随意检查出来。