如何防止WPF编辑框在编程SelectAll上滚动结束?
我有一个文本框,它在获得焦点时执行SelectAll()。效果很好。问题是,如果框中的内容不合适,则SelectAll会导致内容滚动到最后。我希望它滚动到前面,而不是-这个框正在与数字字段一起使用 我的问题是:是否可以选择All()但避免滚动 我现在的解决办法是排队等候一个ScrollToHome。我不太喜欢这个,因为当文本在一个位置呈现时,它有时会导致弹出如何防止WPF编辑框在编程SelectAll上滚动结束?,wpf,Wpf,我有一个文本框,它在获得焦点时执行SelectAll()。效果很好。问题是,如果框中的内容不合适,则SelectAll会导致内容滚动到最后。我希望它滚动到前面,而不是-这个框正在与数字字段一起使用 我的问题是:是否可以选择All()但避免滚动 我现在的解决办法是排队等候一个ScrollToHome。我不太喜欢这个,因为当文本在一个位置呈现时,它有时会导致弹出 public new void SelectAll() { base.SelectAll();
public new void SelectAll()
{
base.SelectAll();
// changing selection does something with a queued scroll request, so have to queue ours in the back. this still may cause a flash
// if a render slips through. would like to find a better way to do this.
Dispatcher.BeginInvoke(DispatcherPriority.Background, ScrollToHome);
}
请注意,ScrollToHome必须像这样排队,否则它会由于其他排队事件而被“覆盖”。我猜是textbox系统内部的notify changed事件。我翻遍了源代码,它非常复杂,很难准确地找出它在哪里执行滚动请求
因此,我要寻找的是以下内容之一:
BeginChange()
和EndChange()
包装您的SelectAll()
和ScrollToHome()
调用。这将避免重新绘制:
public new void SelectAll()
{
BeginChange();
SelectAll();
ScrollToHome();
EndChange();
}
另一种选择是在
文本框
上失去焦点,然后进行选择。我遇到了完全相同的问题(文本框在获得焦点时选择所有,我希望它滚动到开始而不是结束),但在silverlight中。这里没有开始改变/结束改变,所以我基本上也想到了Scott Bilas的答案
这意味着我看到了重新油漆,这是令人沮丧的,但这是我现在能想到的最好的。为了使它更具黑客性,仅仅一个BeginInvoke是不够的,因为自动滚动到底部是排队的,有时会在BeginInvoke操作之后发生,所以我必须引入一个人工延迟(在BeginInvoke之前生成新线程并睡眠10毫秒),以使它更可靠。所以我就这样结束了:
var scrollViewer = VisualTreeWalker.FindVisualChildren<ScrollViewer>(TextBox)
.FirstOrDefault();
new Thread(delegate()
{
Thread.Sleep(10);
scrollViewer.Dispatcher.BeginInvoke(() =>
{
scrollViewer.ScrollToLeft();
scrollViewer.ScrollToTop();
});
}).Start();
var scrollViewer=VisualTreeWalker.FindVisualChildren(文本框)
.FirstOrDefault();
新线程(委托()
{
睡眠(10);
scrollViewer.Dispatcher.BeginInvoke(()=>
{
scrollViewer.ScrollToLeft();
scrollViewer.ScrollToTop();
});
}).Start();
我在文本框中使用依赖属性观察程序来观察ScrollViewer的HorizontalOffset,然后在HorizontalOffset变为非零时执行BeginInvoke,但这需要太多的特殊情况。。如果文本框中没有足够的文本导致自动滚动,从而使水平偏移保持在0,该怎么办?然后,应该引起滚动的合法用户编辑将被滚动回顶部/左侧。它只是变成了一个大兔子洞,所以我不得不满足于这个可怕的黑客