1

我想使用 C#/XAML 在 Windows 8 UI / Metro UI 应用程序中的文本框上实现自动完成。

目前,当软/触摸键盘显示时,它会遮挡自动完成框。但是,在文本框焦点上,Windows 8 会自动向上滚动整个视图并确保文本框处于焦点位置。

实际上,我想要的只是向上滚动一点的视图(实际上是自动完成框的高度)。

我意识到我可以拦截 InputPane.GetForCurrentView() 的 Showing 事件

我可以在 Showing 事件中将 InputPaneVisibilityEventArgs.EnsuredFocusedElementInView 设置为 true(这样 Windows 不会尝试做任何事情)......但是,我如何调用与 Windows 8 相同的滚动功能,但要求它滚动再多一点!?

这是主页的代码:

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,200,0,0">
        <TextBlock HorizontalAlignment="Center" FontSize="60">App 1</TextBlock>
        <TextBlock HorizontalAlignment="Center">Enter text below</TextBlock>
        <TextBox HorizontalAlignment="Center" Margin="-10,0,10,0" Width="400" Height="30"/>
        <ListBox HorizontalAlignment="Center" Width="400">
            <ListBoxItem>Auto complete item 1</ListBoxItem>
            <ListBoxItem>Auto complete item 2</ListBoxItem>
            <ListBoxItem>Auto complete item 3</ListBoxItem>
            <ListBoxItem>Auto complete item 4</ListBoxItem>
            <ListBoxItem>Auto complete item 5</ListBoxItem>
        </ListBox>
    </StackPanel>
</Grid>

如果您以最低分辨率启动模拟器,请用手“触摸”文本框,这将调出软键盘。在真实的应用程序中,当用户输入文本时,自动完成列表将与项目一起出现。

所以简而言之,我怎样才能将屏幕向上移动一点,以便用户可以看到整个自动完成列表?

请记住,在真正的应用程序中,情况会更糟,因为用户甚至可能没有注意到出现在键盘“下方”的自动完成列表。

我真的很感激一些建议,非常感谢!

4

2 回答 2

4

我已经为 Windows 应用商店应用程序创建了一个 AutoCompleteBox,nuget 包可在https://nuget.org/packages/AutoCompleteBoxWinRT

于 2012-12-17T22:24:54.543 回答
0

好的,这就是我将如何解决这个问题,因为我似乎找不到任何方法来根据键盘的外观来控制应用程序的滚动。我将创建一个用户控件,该控件将构成自动完成文本框的基础。

<UserControl
x:Class="App6.MyUserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App6"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">

<Grid>
    <TextBox x:Name="textBox" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top"  GotFocus="textBox_GotFocus" LostFocus="textBox_LostFocus" />
    <ListBox x:Name="listBox" Height="150"  Margin="0,-150,0,0" VerticalAlignment="Top" Visibility="Collapsed"/>
</Grid>

这是一个非常基本的实现,因此您必须进行调整以满足您的需求。

然后,我将以下代码隐藏添加到用户控件

public sealed partial class MyUserControl1 : UserControl
{
    // Rect occludedRect;
    bool hasFocus = false;

    public MyUserControl1()
    {
        this.InitializeComponent();
        InputPane.GetForCurrentView().Showing += MyUserControl1_Showing;
    }

    void MyUserControl1_Showing(InputPane sender, InputPaneVisibilityEventArgs args)
    {
        if (hasFocus)
        {
            var occludedRect = args.OccludedRect;

            var element = textBox.TransformToVisual(null);
            var point = element.TransformPoint(new Point(0, 0));

            if (occludedRect.Top < point.Y + textBox.ActualHeight + listBox.ActualHeight)
            {
                listBox.Margin = new Thickness(0, -listBox.ActualHeight, 0, 0);         // Draw above     
            }
            else
            {
                listBox.Margin = new Thickness(0, textBox.ActualHeight, 0, 0); // draw below
            }
        }          
    }

    private void textBox_GotFocus(object sender, RoutedEventArgs e)
    {
        listBox.Visibility = Windows.UI.Xaml.Visibility.Visible;
        hasFocus = true;
    }

    private void textBox_LostFocus(object sender, RoutedEventArgs e)
    {
        listBox.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
        hasFocus = false;
    }        
}

接下来的步骤是公开属性以传递要绑定到 ListBox 的数据。硬核将是 ListBoxItem 模板等等,具体取决于您希望它的可重用程度。

于 2012-08-21T00:41:48.057 回答