我试图在元素滚动到视图时收到通知,
据我了解,ScrollViewer 在其子元素上调用 BringIntoView,然后子元素引发 RequestBringIntoView 事件,ScrollViewer 稍后会捕获并处理该事件。
这是通过为此事件注册一个类处理程序并在它冒泡时捕获它来完成的
EventManager.RegisterClassHandler(typeof(ScrollViewer), RequestBringIntoViewEvent, new RequestBringIntoViewEventHandler(OnRequestBringIntoView));
我需要的是在每次发生此过程时得到通知,我的尝试是从 ScrollViewer 派生并创建我自己的类型事件并以两种方式之一处理它:
1) 为同一事件添加一个类处理程序,最后为 true 以处理 Handled events 。
2) 创建我自己的事件来处理 RequestBringIntoViewEvent 类型的事件
public class NotifyOnBringIntoViewScrollViewer : ScrollViewer
{
static NotifyOnBringIntoViewScrollViewer()
{
// for secnario (2) replace RequestBringIntoViewEvent with Noti
EventManager.RegisterClassHandler(typeof(NotifyOnBringIntoViewScrollViewer),RequestBringIntoViewEvent , new RequestBringIntoViewEventHandler(OnRequestBringIntoView), true);
}
public static readonly RoutedEvent NotifyBringIntoViewEvent = EventManager.RegisterRoutedEvent(
"NotifyBringIntoView", RoutingStrategy.Direct, typeof(RequestBringIntoViewEventHandler), typeof(NotifyOnBringIntoViewScrollViewer));
private static void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
// notify ..
}
}
由于一个或两个原因,从未联系到处理程序,
1)我想念路由事件在注册处理程序方面的工作方式。2)我的子元素从不提出 RequestBringIntoView ,我的尝试如下:
CS :
public List<int> Items
{
get
{
return new List<int>
{
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25
};
}
}
xml:
<local:NotifyOnBringIntoViewScrollViewer>
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</local:NotifyOnBringIntoViewScrollViewer>
仅供参考: VirtualizingStackPanel,我放这个是因为我不确定这是默认面板,如果没有调用 Virtualizing BringIntoView,因为它们已经在视图中。