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 事件处理程序检测点击的垂直位置,并滚动 ScrollViewer,以便在 TextBox 获得焦点时显示插入符号。

于 2012-05-28T18:52:40.740 回答
1

也许这不是一个最好的解决方案,但它的工作:

xml:

<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时禁用(向上移动)的转换。TextBox此外,当键盘在屏幕上时,此代码执行新的空闲屏幕高度管理。

于 2012-05-25T20:23:32.660 回答