2

我需要为 WPF TextBox 控件的内容添加一些装饰。这基本上可以正常工作,我可以获得指定字符索引的位置并相应地布局我的其他元素。但是当滚动 TextBox 时,这一切都会中断。我的布局位置不再与显示的文本匹配,因为它已移动到其他地方。

现在我很惊讶 TextBox 类没有提供有关其滚动状态的任何信息,也没有提供滚动更改时的任何事件。我现在能做什么?

我使用 Snoop 找出是否有一些我可以询问的滚动子元素,但 ScrollContentPresenter 也没有任何可用的滚动信息。我真的很想将我的装饰元素直接放入滚动区域,以便滚动也可以影响它们,但是只能有一个内容控件,这已经是 TextBox 内部结构之一。

4

2 回答 2

7

我不确定如何在滚动文本框时捕获事件(可能使用 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;
}
于 2014-02-05T16:50:26.283 回答
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
}
于 2013-02-15T22:28:50.217 回答