我正在尝试在元素滚动到视图时收到通知,
据我所知,ScrollViewer在它的子元素上调用BringIntoView然后 子元素引发了ScrollViewer后来捕获的RequestBringIntoView事件 并处理。
这是通过注册此事件的类处理程序并在其冒泡时捕获它来完成的
EventManager.RegisterClassHandler(typeof(ScrollViewer), RequestBringIntoViewEvent, new RequestBringIntoViewEventHandler(OnRequestBringIntoView));
我需要的是每次进行此过程时都会收到通知,我的尝试是从中获得 ScrollViewer和创建我自己的类型事件并以两种方式之一接近它:
1)为同一事件添加一个类处理程序,最后用true处理Handled事件。
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
};
}
}
xaml:
<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,我说这是因为我不确定这是默认面板 如果没有虚拟化BringIntoView被调用,因为它们已经在视图中。