MenuFlyoutItem.KeyboardAccelerators 两次触发 Invoked 事件

MenuFlyoutItem.KeyboardAccelerators fires Invoked event twice

我已经实现了 MenuFlyoutItem.KeyboardAccelerators 下面你可以看到代码

Xaml代码

        <Button Content="Edit Options"
            Width="100"
            Height="100"
            HorizontalAlignment="Right">
        <Button.Flyout>
            <MenuFlyout>
                <MenuFlyoutItem x:Name="FlyoutItem1" Text="Copy" Icon="Copy">
                    <MenuFlyoutItem.KeyboardAccelerators>
                        <KeyboardAccelerator x:Name="Test" Key="C" Modifiers="Control" Invoked="Test_Invoked" />
                    </MenuFlyoutItem.KeyboardAccelerators>
                </MenuFlyoutItem>
                <MenuFlyoutSeparator/>
            </MenuFlyout>
        </Button.Flyout>
    </Button>

代码隐藏

    public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }
    private void Test_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
    {
        Debug.WriteLine($">>>>>>>>>>>>>>>>>>>>>>>>>>>>> invoked Hash = {sender.GetHashCode()}");
    }
}

在单击应用程序中的按钮之前,CTRL+C 热键操作会触发一个事件。但是,当我单击按钮并出现 MenuFlyout 时,Ctrl+C 热键操作会触发两次相同的事件。当我再次单击应用程序事件中的另一个地方时,通常只会触发一次。


如果您想测试应用程序,请遵循此 link enter link description here

根据Mircrosoft Documentation about KeyboardAccelerator

By default, an accelerator has global scope. However, you can constrain scope using ScopeOwner or disable an accelerator completely using IsEnabled.

我不知道这是一个错误还是他们没有在文档中描述的行为,但是如果您在同一范围内有多个 KeyboardAccelerator,那么如果您专注于该元素,它会触发两次包含 KeyboardAccelerator。

解决方案。

因此,在您的情况下,您需要指定 KeyboardAccelerator 的范围,它只会在该范围内触发一次。

重要!

您只需使用 x:Bind 绑定 ScopeOwner。它不适用于 Binding。

<Button Content="Edit Options"
        x:Name="button"
        Width="100"
        Height="100"
        HorizontalAlignment="Right">
    <Button.Flyout>
        <MenuFlyout>
            <MenuFlyoutItem x:Name="FlyoutItem1" Text="Copy" Icon="Copy">
                <MenuFlyoutItem.KeyboardAccelerators>
                    <KeyboardAccelerator x:Name="Test" Key="C" Modifiers="Control" Invoked="Test_Invoked" ScopeOwner="{x:Bind button}" />
                </MenuFlyoutItem.KeyboardAccelerators>
            </MenuFlyoutItem>
            <MenuFlyoutSeparator/>
        </MenuFlyout>
    </Button.Flyout>
</Button>