我需要在WPF TextBox控件的内容中添加一些装饰。基本上工作正常,我可以获得指定字符索引的位置,并相应地布局我的其他元素。但是当TextBox滚动时,它都会中断。我的布局位置不再与显示的文本匹配,因为它已移动到其他位置。
现在我很惊讶TextBox类没有提供有关其滚动状态的任何信息,也没有提供滚动更改时的任何事件。我现在能做什么?
我使用Snoop来确定是否有一些我可以问的滚动子元素,但ScrollContentPresenter也没有任何可用的滚动信息。我真的想把我的装饰元素放到滚动区域中,这样滚动也会影响它们,但是只能有一个内容控件,而且它已经是TextBox内部的一个。
答案 0 :(得分:5)
我不确定如何在滚动文本框时捕获事件(可能使用narohi的答案),但有一种简单的方法可以查看当前滚动位置:
// Gets or sets the vertical scroll position.
textBox.VerticalOffset
我正在使用它来查看文本框是否滚动到最后,如下所示:
public static bool IsScrolledToEnd(this TextBox textBox)
{
return textBox.VerticalOffset + textBox.ViewportHeight == textBox.ExtentHeight;
}
答案 1 :(得分: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
}