Windows 8/Metro UI中文本框下方的自动完成框 [英] Auto-complete box under a text box in Windows 8 / Metro UI

查看:72
本文介绍了Windows 8/Metro UI中文本框下方的自动完成框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to implement auto-complete on a textbox in a Windows 8 UI / Metro UI app using C#/XAML.

此刻,当软/触摸键盘显示时,它会遮盖自动完成框.但是,在文本框焦点上,Windows 8会自动向上滚动整个视图,并确保文本框处于焦点状态.

At the moment, when the soft / touch keyboard shows, it obscures the auto-complete box. However, on the text box focus, Windows 8 automatically scrolls the entire view up and ensures the text box is in focus.

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

In reality, all I want is the view to scroll up a little more (in fact, by the height of the auto-complete box).

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

I realise I can intercept the Showing event of InputPane.GetForCurrentView()

我可以在Showing事件内将InputPaneVisibilityEventArgs.EnsuredFocusedElementInView设置为true(这样Windows不会尝试执行任何操作)....但是,如何调用与Windows 8相同的滚动功能,但是请问一下再滚动一点!?

I can set InputPaneVisibilityEventArgs.EnsuredFocusedElementInView to true inside the Showing event fine (so Windows won't try to do anything).... however, how can I invoke the same scrolling functionality that Windows 8 would do, but ask it to scroll a little more!?

这是主页的代码:

    <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>

如果以最低分辨率启动模拟器,请用一只手触摸"文本框,这将弹出软键盘.在实际的应用程序中,当用户输入文本时,自动完成列表将与项目一起显示.

If you start up the simulator with the lowest resolution, use the hand to "touch" the textbox, this will bring up the soft keyboard. In the real app, the auto complete list will appear with items as the user enters text.

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

So in a nutshell, how can I move the screen up a bit more so the user can see the entire autocomplete list?

请记住,在实际应用中,情况会更糟,因为用户甚至可能不会注意到自动完成列表出现在键盘下方".

Bear in mind, in the real app, it'll be worse, as the user may not even notice the autocomplete list appearing "underneath" the keyboard.

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

I really would appreciate some advice, many thanks!

推荐答案

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

Ok, here is how I would tackle this since I cannot seem to find any way to control the scrolling of the app based on the appearance of the keyboard. I would create a user control that would form the basis for the auto-complete textbox.

<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>

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

This is an incredibly basic implementation, so you will have to tweak to meet your needs.

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

Then, I would add the following code-behind to the user control

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模板,以及更多,取决于您希望它具有多大的可重用性.

Next steps would be to expose properties to pass data to be bound to the ListBox. Hard core would be ListBoxItem templating and more, depending on how reusable you wanted it to be.

这篇关于Windows 8/Metro UI中文本框下方的自动完成框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆