3

テキストボックスの垂直セットを含むページがあります。それらの 1 つがフォーカスされている場合、オンスクリーン キーボードが表示されていても、それらすべてが表示されます。それらのすべてがキーボードの上の利用可能なスペースに収まるのに十分な数があります. 下部のテキスト ボックスがフォーカスされると、ページは自動的に上にスクロールされてすべてが表示されますが、上部のテキスト ボックスがフォーカスされると、オンスクリーン キーボードが下部のテキスト ボックスを覆います。

これは私のページの簡単な例です:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <ItemsControl ItemsSource="{Binding List}" Margin="120 140 0 0">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Margin="0 10 0 0">
                    <TextBox Text="{Binding Text, Mode=TwoWay}" />
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

DataContext10 項目のリストが含まれています。

public class Item
{
    public string Text { get; set; }
}

public class ViewModel
{
    public List<Item> List { get; set; }
}

public MainPage()
{
    this.InitializeComponent();
    DataContext = new ViewModel
    {
        List = Enumerable.Range(0, 10).Select(i => new Item { Text = i.ToString() }).ToList()
    };
}

私はすでにいくつかのアプローチを試しましたが、すべて成功しませんでした:

  1. イベントではTextBox.GotFocus、プログラムでフォーカスを下部のテキストボックスに変更して戻しました。
  2. TextBox.GotFocusイベントとInputPane.Showingイベントで、a の垂直オフセットを設定しようとしました: ScrollViewer(a) ページの周りに含めたものGrid(b) 上記のビジュアル ツリーにあるPageもの。Windows は、フォーカスされたコントロールを自動的に表示するために使用します。どちらの場合も、は呼び出しScrollViewerに反応しません。ScrollToVerticalOffset

この質問で提案されているサンプルも見ましたが、ページをスクロールするのではなく、オンスクリーンキーボードへの反応が異なります。

4

2 に答える 2

8

Cyprientの答えのおかげで、私はついにこれを機能させることができました。私は私の質問からオプション2.aを追求しました。

呼び出しを追加するUpdateLayout()必要がありましたが、イベントハンドラーに入れるとGotFocus、仮想キーボードが既に開かれた後にのみ機能しました。キーボードがまだ開いているときに初めて動作させるには、2つの変更を加える必要がありました。

  1. Showingの場合にコードを配置する必要がありましたInputPane
  2. Showingイベントハンドラーが既に戻った後にのみ呼び出されるように、ディスパッチャーのコールバックに配置する必要がありました。

最終的なコードは次のとおりです。

public MainPage()
{
    this.InitializeComponent();
    DataContext = new ViewModel
    {
        List = Enumerable.Range(0, 10).Select(i => new Item { Text = i.ToString() }).ToList()
    };

    var inputPane = InputPane.GetForCurrentView();
    inputPane.Showing += InputPane_Showing;
}

private async void InputPane_Showing(InputPane sender, InputPaneVisibilityEventArgs args)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            var parentScrollViewer = FindParent<ScrollViewer>(this.pageRoot);
            parentScrollViewer.VerticalScrollMode = ScrollMode.Enabled;
            parentScrollViewer.ScrollToVerticalOffset(65);
            parentScrollViewer.UpdateLayout();
        });
}

ScrollViewerフォーカスされたコントロールが表示されないため、ページのコンテンツが自動的にスクロールされるときに使用されるものへの参照を取得するために使用しているヘルパー関数は次のとおりです。

public static T FindParent<T>(FrameworkElement reference)
    where T : FrameworkElement
{
    FrameworkElement parent = reference;
    while (parent != null)
    {
        parent = parent.Parent as FrameworkElement;

        var rc = parent as T;
        if (rc != null)
        {
            return rc;
        }
    }

    return null;
}
于 2012-10-03T10:16:17.843 に答える
3

ScrollToVerticalOffset を使用している場合、ScrollViewer が更新されないことがあります。回避策は、スクロール後に scrollviewer.UpdateLayout() を呼び出すことです。いくつかのケースでうまくいきました。

于 2012-09-28T14:57:13.410 に答える