2012-05-25 33 views
2

基本上,我正在開發一個筆記記錄應用程序,用戶只要他想輸入便可(類似Scrollable TextBox in WP7)。我把文本框放在ScrollViewer中,一切都很好;當TextBox獲得焦點時,我禁用ScrollViewer,因此它在用戶輸入時自動滾動。WP7中的可滾動文本框(ala Skype和Facebook)

我的問題是,我希望用戶能夠在編輯筆記時進行滾動,就像他能夠在閱讀筆記時滾動一樣。我認爲要做到這一點的唯一方法就是堅持到超大號插入符號出現,然後移動它,但我發現實際上第三方應用程序支持這種類型的滾動。

我想要實現的是類似電話上的Word/OneNote,用戶在編輯文檔時可以輕鬆滾動(here's a video)。在Skype和Facebook應用程序中可以看到同樣的效果,在寫消息時,您可以滾動瀏覽以查看更多內容。

我不知道這是一個自定義控件,還是佈局是以特定方式設計的,因爲ScrollViewer內的TextBox不起作用。

我很感激任何幫助。提前致謝。

回答

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); 
    } 
} 

輕按事件處理程序檢測抽頭的垂直位置,和滾動的ScrollViewer所以插入符是鑑於當文本框獲得焦點。

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改造(向上移動)時TextBox得到專注。此外,此代碼在鍵盤在屏幕上時執行新的自由屏幕高度管理。

+0

非常感謝,您的代碼似乎工作。但是,有一些錯誤:出於某種原因,我無法完全滾動,所以我無法訪問TextBox(我必須將其移動到頂部)。另外,當TextBox獲得焦點時,它將不可見,所以我必須向上滾動才能找到它。最後,當我輸入第一個字母時,它會再次出現,因此我必須再次滾動。 有沒有一種方法可以正常行爲,但只是能夠滾動? –

+0

我只是在模擬器和設備上測試它,所有的作品都像一個魅力。看看完整的項目在這裏:http://depositfiles.com/files/ur1xncss0 – Ku6opr

+0

我認爲這個問題是一旦你使用不同的佈局,它停止工作(部分因爲ScrollViewer的高度=「800」)。我幾乎已經完成了代碼的調整,唯一缺少的就是自動滾動到插入位置(InputScrollViewer.ScrollToVerticalOffset可以在大多數情況下工作,但有時它會滾過插入符號)。如果有辦法檢測插入符號的垂直位置,它將全部設置! –