2013-02-15 97 views
1

我需要添加一些裝飾到WPF文本框控件的內容。基本上工作正常,我可以獲得指定字符索引的位置並相應地佈局我的其他元素。但是當TextBox滾動時它全部中斷。我的佈局位置與顯示的文本不再匹配,因爲它已移動到別處。獲取WPF文本框的滾動位置

現在我很驚訝TextBox類不提供任何有關其滾動狀態的信息,也沒有任何滾動更改時的事件。我現在能做什麼?

我用Snoop找出是否有一些滾動子元素,我可以問,但ScrollContentPresenter也沒有任何滾動信息可用。我真的很想將我的裝飾元素直接放入滾動區域,以便滾動也可以影響它們,但是隻能有一個內容控件,並且這是TextBox內部的一個。

+0

也許嘗試訂閱ScrollViewer.ScrollChanged路由事件?它提供的信息包括範圍高度,滾動偏移量,視口大小(全部在水平和垂直方向),也許會有所幫助。雖然我不完全明白你的任務。但試試看吧。 – Haspemulator 2013-02-15 21:13:53

回答

1

你可以通過傳入你的文本框作爲參數和ScrollView類型來獲得ScrollViewer的這個方法。然後你可以訂閱ScrollChanged事件。

public static T FindDescendant<T>(DependencyObject obj) where T : DependencyObject 
{ 
    if (obj == null) return default(T); 
    int numberChildren = VisualTreeHelper.GetChildrenCount(obj); 
    if (numberChildren == 0) return default(T); 

    for (int i = 0; i < numberChildren; i++) 
    { 
     DependencyObject child = VisualTreeHelper.GetChild(obj, i); 
     if (child is T) 
     { 
      return (T)(object)child; 
     } 
    } 

    for (int i = 0; i < numberChildren; i++) 
    { 
     DependencyObject child = VisualTreeHelper.GetChild(obj, i); 
     var potentialMatch = FindDescendant<T>(child); 
     if (potentialMatch != default(T)) 
     { 
      return potentialMatch; 
     } 
    } 

    return default(T); 
} 

例子:

public MainWindow() 
{ 
    InitializeComponent(); 
    Loaded += new RoutedEventHandler(MainWindow_Loaded); 
} 

void MainWindow_Loaded(object sender, RoutedEventArgs e) 
{ 
    ScrollViewer s = FindDescendant<ScrollViewer>(txtYourTextBox); 
    s.ScrollChanged += new ScrollChangedEventHandler(s_ScrollChanged); 
} 

void s_ScrollChanged(object sender, ScrollChangedEventArgs e) 
{ 
    // check event args for information needed 
} 
4

我不知道如何當文本已滾動(可能使用narohi對這個問題的答案)捕捉事件,但有一個簡單的方法,看看有什麼當前滾動的位置是:

// Gets or sets the vertical scroll position. 
textBox.VerticalOffset 

(從http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.textboxbase.verticaloffset(v=vs.100).aspx

我用它來看看文本框是否滾動到最後,像這樣:

public static bool IsScrolledToEnd(this TextBox textBox) 
{ 
    return textBox.VerticalOffset + textBox.ViewportHeight == textBox.ExtentHeight; 
} 
+0

約翰,謝謝,我試過你的IsScrolledToEnd。它通常有效,但並非總是如此。問題是你正在比較==運算符的雙打。我認爲在這個比較中應該有1行寬容,就像這樣:'bool scrollToEnd = Memo.VerticalOffset> Memo.ExtentHeight - Memo.ViewportHeight - fontHeight;' – Aleksandr 2017-12-12 07:53:18