您可以使用 Lester 的 WPF\SL 博客上的Determining the Visibility of Elements inside ScrollViewer 一文中的方法来确定特定项目是否可见ScrollViewer
。从那个博客:
// position of your visual inside the scrollviewer
GeneralTransform childTransform = ContainedObject.TransformToAncestor(ScrollViewerObj);
Rect rectangle = childTransform.TransformBounds(new Rect(new Point(0,0),
ContainedObject.RenderSize));
// Check if the elements Rect intersects with that of the scrollviewer's
Rect result = Rect.Intersect(new Rect(new Point(0, 0), ScrollViewerObj.RenderSize),
rectangle);
// if result is Empty then the element is not in view
if (result == Rect.Empty)
{
ContainedObject.IsPopupOpen = false; // <<< Close relevant popup here
}
else
{
//obj is partially Or completely visible
//skip or bring obj in view.
}
显然,要使其工作,您需要向bool IsPopupOpen
数据绑定到属性的数据对象添加一个新TextBox.Text
属性。然后你也需要Bind
这个Popup.IsOpen
属性:
<Popup IsOpen="{Binding IsPopupOpen}" StaysOpen="False" ... />
更新>>>
当滚动a 时,该ScrollViewer.ScrollChanged
事件将被经常调用。ScrollViewer
直接在该事件处理程序中执行任何代码确实是不明智的,但是该ScrollChangedEventArgs
对象具有一些可以帮助我们的属性。有关这些属性的完整详细信息,请查看 MSDN 上的ScrollChangedEventArgs
Class页面。
您可以在名为的事件处理程序中访问两个属性,VerticalChange
它们应该向您显示自上次事件以来滚动HorizontalChange
了多少。ScrollViewer
[现在已经有一段时间了,所以我不能保证它们是正确的属性,但是如果您在事件处理程序中使用 MSDN 上的“ScrollChangedEventArgs.VerticalChange
属性”页面中的示例代码,读出的内容应该会给您一个线索,哪些是要使用的正确属性。]
因此,找到相关属性后,您可以在处理程序中使用它们来确定是否执行您的代码......尝试这样的事情:
double totalVerticalChange = 0.0;
double minimumValue = 24.0; // set this to whatever you want as a minimum scroll value
...
private void ScrollViewer_Changed(object sender, ScrollChangedEventArgs e)
{
if (totalVerticalChange + e.VerticalChange >= minimumValue)
{
totalVerticalChange = 0.0;
// perform your functionality here
}
else totalVerticalChange += e.VerticalChange;
}
如果这里有错误,请原谅我,因为我目前无法在 Visual Studio 中检查这一点,但希望你能明白……本质上,这就像我们正在“过滤”掉一些事件。