2

基本的に、私はユーザーが好きなだけ入力できるメモアプリを開発しています( WP7のScrollable TextBoxのようなものです)。TextBoxをScrollViewerに入れましたが、すべて問題ありません。TextBoxがフォーカスを取得したときにScrollViewerを無効にするので、ユーザーが入力している間は自動的にスクロールします。

私の問題は、ユーザーがメモを読んでいるときにスクロールできるのと同じように、ユーザーがメモを編集しているときにスクロールできるようにしたいということです。これを行う唯一の方法は、特大のカレットが表示されるまで押し続けてから移動することだと思いましたが、実際、サードパーティのアプリがこのタイプのスクロールをサポートしていることを発見しました。

私が達成しようとしているのは、電話のWord / OneNoteのようなもので、ユーザーはドキュメントを編集しながら簡単にスクロールできます(これはそれを示すビデオです)。同じ効果がSkypeアプリとFacebookアプリでも見られます。メッセージを書いているときに、メッセージをスクロールして詳細を表示できます。

ScrollViewer内のTextBoxは単に機能しないため、これがカスタムコントロールなのか、それともレイアウトが特定の方法で設計されたのか疑問に思います。

助けていただければ幸いです。前もって感謝します。

4

2 に答える 2

3

Ku6opr からの回答に基づいて、私の状況で動作するようにコードを微調整しました。現在、TextBox は通常の動作をしていますが、スクロール可能であり、RootFrame は自動的には上がりません。

XAML:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <ScrollViewer x:Name="InputScrollViewer">
        <TextBox x:Name="MessageText" TextWrapping="Wrap" Text="" AcceptsReturn="True" TextChanged="inputText_TextChanged" GotFocus="MessageText_GotFocus" Padding="0,0,0,400" Tap="MessageText_Tap" />
    </ScrollViewer>
</Grid>

C#:

public partial class MainPage : PhoneApplicationPage
{
    double InputHeight = 0.0;

    // Constructor
    public MainPage()
    {
        InitializeComponent();
    }

    private void MessageText_GotFocus(object sender, System.Windows.RoutedEventArgs e)
    {
        (App.Current as App).RootFrame.RenderTransform = new CompositeTransform();
    }

    private void inputText_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
    {
        Dispatcher.BeginInvoke(() =>
        {
            double CurrentInputHeight = MessageText.ActualHeight;

            if (CurrentInputHeight > InputHeight)
            {
                InputScrollViewer.ScrollToVerticalOffset(InputScrollViewer.VerticalOffset + CurrentInputHeight - InputHeight);
            }

            InputHeight = CurrentInputHeight;
        });
    }

    public void MessageText_Tap(object sender, GestureEventArgs e)
    {
        InputScrollViewer.ScrollToVerticalOffset(e.GetPosition(MessageText).Y - 80);
    }
}

Tap イベント ハンドラーはタップの垂直位置を検出し、TextBox がフォーカスを取得したときにキャレットが表示されるように ScrollViewer をスクロールします。

于 2012-05-28T18:52:40.740 に答える
1

たぶんそれは最善の解決策ではないかもしれませんが、うまくいきます:

xaml:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <ScrollViewer x:Name="InputScrollViewer" Margin="12,0" Height="800" VerticalAlignment="Top">
        <StackPanel Orientation="Vertical" Margin="0,12">
            <TextBlock TextWrapping="Wrap" Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in ligula augue. Morbi facilisis varius enim in congue. Nam vehicula imperdiet ipsum in ullamcorper. Integer quis augue in dui tincidunt elementum. Nulla in mi mauris, eu laoreet leo. Sed vehicula quam nec leo imperdiet a rutrum felis viverra." Style="{StaticResource PhoneTextNormalStyle}" Margin="12,12,12,0"/>
            <TextBlock TextWrapping="Wrap" Text="Morbi molestie facilisis eleifend. Cras volutpat, lectus nec tincidunt accumsan, mi purus faucibus purus, vitae semper mauris lacus id mauris. Fusce eget massa ut magna lacinia gravida. Ut id velit purus. Nullam eu mi ac justo imperdiet pretium. Curabitur vehicula congue purus vitae sollicitudin." Style="{StaticResource PhoneTextNormalStyle}" Margin="12,12,12,0"/>
            <TextBlock TextWrapping="Wrap" Text="Aenean eget dui a urna commodo faucibus sit amet nec eros. Nam tempus facilisis urna, ut varius justo euismod sit amet. Vivamus ultrices volutpat tortor in viverra. Vestibulum laoreet odio at tellus consectetur ut convallis quam semper. Duis in iaculis lectus. Aliquam erat volutpat. Nulla facilisi. Quisque vitae metus lorem. Fusce et erat nisl, sit amet gravida libero. Cras elementum eros vitae tellus sollicitudin accumsan. Pellentesque egestas luctus bibendum. Duis eros ipsum, mollis ut laoreet eu, consectetur id lectus. Maecenas viverra risus urna." Style="{StaticResource PhoneTextNormalStyle}" Margin="12,12,12,0"/>
            <TextBox x:Name="MessageText" TextWrapping="Wrap" Text="" AcceptsReturn="True" TextChanged="inputText_TextChanged" GotFocus="MessageText_GotFocus" LostFocus="MessageText_LostFocus"/>
        </StackPanel>
    </ScrollViewer>
</Grid>

コード ビハインド:

public partial class MainPage : PhoneApplicationPage
{
    bool IsInputFocused = false;
    double InputHeight = 0.0;
    double KeyboardHeight = 338;
    double KeyboardClipboardHeight = 72;
    double RootHeight = 800;

    public MainPage()
    {
        InitializeComponent();

        DeviceStatus.KeyboardDeployedChanged += new EventHandler(DeviceStatus_KeyboardDeployedChanged);
    }

    void DeviceStatus_KeyboardDeployedChanged(object sender, EventArgs e)
    {
        if (IsInputFocused)
        {
            UpdateKeyboard();
        }
    }

    private void inputText_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
    {
        Dispatcher.BeginInvoke(() =>
        {
            double CurrentInputHeight = MessageText.ActualHeight;

            if (CurrentInputHeight > InputHeight)
            {
                InputScrollViewer.ScrollToVerticalOffset(InputScrollViewer.VerticalOffset + CurrentInputHeight - InputHeight);
            }

            InputHeight = CurrentInputHeight;
        });
    }

    private void UpdateKeyboard()
    {
        (App.Current as App).RootFrame.RenderTransform = new CompositeTransform();

        if (!DeviceStatus.IsKeyboardDeployed)
        {
            InputScrollViewer.Height = RootHeight - (KeyboardHeight + GetClipboardHeight());
        }
        else
        {
            InputScrollViewer.Height = RootHeight;
        }
    }

    private double GetClipboardHeight()
    {
        return (Clipboard.ContainsText()) ? KeyboardClipboardHeight : 0;
    }

    private void MessageText_GotFocus(object sender, System.Windows.RoutedEventArgs e)
    {
        IsInputFocused = true;

        (App.Current as App).RootFrame.RenderTransform = new CompositeTransform();

        UpdateKeyboard();

        Dispatcher.BeginInvoke(() =>
        {
            InputScrollViewer.ScrollToVerticalOffset(InputScrollViewer.VerticalOffset + 338 + GetClipboardHeight());
        });
    }

    private void MessageText_LostFocus(object sender, System.Windows.RoutedEventArgs e)
    {
        IsInputFocused = false;

        InputScrollViewer.Height = RootHeight;
    }
}

まず、このコードは、フォーカスFrameされたときに a (上に移動)の変換を無効にします。TextBoxまた、このコードは、キーボードが画面上にあるときに、新しい空き画面の高さの管理を実行します。

于 2012-05-25T20:23:32.660 に答える