无法在 Flyout 中的 TextBox 控件中输入文本

15

我想使用CommandBarFlyout来构建类似于以下图片的东西。

search flyout

用户应该点击CommandBar中的按钮(Flyout打开),然后在TextBox中输入文本,然后单击TextBox右侧的按钮以开始搜索请求。问题是,当我单击TextBox时,无法输入文本。似乎在我写入任何内容之前,它就失去了焦点。下面是示例代码。哪里出错了?

<Page.Resources>
    <DataTemplate x:Key="Search">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <TextBox Grid.Column="0" />
            <AppBarButton Grid.Column="1" Icon="Find" />
        </Grid>
    </DataTemplate>
</Page.Resources>

<Grid>
    <CommandBar RequestedTheme="Dark">
        <AppBarButton Icon="Find">
            <AppBarButton.Flyout>
                <Flyout Placement="Bottom" >
                    <ContentPresenter ContentTemplate="{StaticResource Search}"/>
                </Flyout>
            </AppBarButton.Flyout>
        </AppBarButton>
    </CommandBar>
</Grid>

我无法重现你的问题。使用你提供的代码一切都正常。你在代码后台是否有阻塞文本框的操作? - lokusking
在触摸屏设备上要小心,因为屏幕键盘可能会覆盖在弹出框的上方,有效地隐藏文本框。如果您想通过单击屏幕上弹出框外部区域来隐藏键盘,那么这也将关闭弹出框。这不是一个很好的用户体验。 - Jasper
3个回答

25

AppBarButton上将AllowFocusOnInteraction属性设置为true

XAML中的解决方案(如果应用程序最小目标版本为10.0.14393或更高版本)

    <AppBarButton x:Name="myAppBarButton"
                  Icon="Find"
                  AllowFocusOnInteraction="True">
        <AppBarButton.Flyout>
            <Flyout Placement="Bottom" >
                <ContentPresenter ContentTemplate="{StaticResource Search}"/>
            </Flyout>
        </AppBarButton.Flyout>
    </AppBarButton>

如果应用程序的最低版本低于周年更新1607(版本10.0.14393)(即使您的目标版本是1607或更高),则无法直接在XAML中设置AllowFocusOnInteraction属性。相反,您应该在代码后台中执行此操作。

C#代码后台解决方案

// check if the AllowFocusOnInteraction property is available on the platform 
if (Windows.Foundation.Metadata.ApiInformation.IsPropertyPresent("Windows.UI.Xaml.FrameworkElement", "AllowFocusOnInteraction"))
     myAppBarButton.AllowFocusOnInteraction = true;

你还可以将其包装成一个附加属性,即使在旧版Windows 10上也可以在XAML中使用。

更多信息

这是Windows 10周年更新(1607),版本14393上的新功能

对于大多数应用栏使用来说,这是一种改进,但会干扰您的使用,因此当您将构建更改为14393而不是10586时,您需要覆盖默认值。

这里有一篇博客文章 “从AppBarButton创建的Flyout中的ComboBox在1607上失去鼠标输入”。它还包含了该附加属性的实现。


如果在XAML中设置属性,我会遇到编译错误。XBF语法错误'0x09C4':未找到属性。请检查您在XAML中设置的属性是否存在于项目中指定的平台最低版本(TargetPlatformMinVersion)中。 - Rahul Sonone
没错。正如我在答案中所述,你的目标是Windows 10周年更新(1607)版本14393或更高版本,但应用程序的最低Windows 10版本较低,你应该检查平台上是否可用“AllowFocusOnInteraction”属性。因此,你不能在XAML中设置“AllowFocusOnInteraction”属性。相反,你应该在代码后端进行设置。 - Artemious
1
另一种解决方案是创建一个附加属性来封装此行为,并在XAML中使用该附加属性。 - Artemious
我做了相同的附加属性@Artemious。 - Rahul Sonone

1

您的文本框实际上根本没有获得焦点,某种方式飞出窗口阻止了它,我可以从这个文本框中获取的唯一操作是PointerOver状态-使其看起来像它已经获得焦点,但实际上并没有。

您需要在代码中设置焦点,例如当弹出窗口打开时-它可以工作,但可能不是最好的解决方案,因为您需要命名文本框才能从后台代码中获取它。

<Grid>
    <CommandBar RequestedTheme="Dark">
        <AppBarButton Icon="Find">
            <AppBarButton.Flyout>
                <Flyout Placement="Bottom" Opened="FlyoutBase_OnOpened">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="200" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <TextBox x:Name="Test"/>
                        <AppBarButton Grid.Column="1" Icon="Find"/>
                    </Grid>
                </Flyout>
            </AppBarButton.Flyout>
        </AppBarButton>
    </CommandBar>
</Grid>

然后是代码后台:
private void FlyoutBase_OnOpened(object sender, object e)
{
    Test.Focus(FocusState.Programmatic);
}

这是框架中的一个错误还是在代码后台设置焦点是正常的? - M.Stack
看起来像是一个bug,特别是如果Toth Tibor所写的(它只发生在周年更新中)是真的。在代码后台设置焦点更像是“hack”,绝对不是好的解决方案(但确实有效)。微软会修复这个问题吗?还有许多其他UWP相关的bug,微软已经很久没有修复了,所以我宁愿不等待它。特别是如果没有地方可以发布bug报告的话。 - RTDev

0

我可以重现这个问题。我认为这是周年更新(1607)SDK(14393)中的一个错误,因为如果我将目标SDK降级到10586,一切都正常。

附:我不知道如何向微软报告此错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接