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