我在WinRT的ListView中遇到过这种行为。
如果没有事件处理程序附加到内部LayoutUpdated
的{{1}}事件,则 ScrollViewer
事件的触发次数会减少。
我用LayoutUpdated
标记了底部附近的关键线。
删除前导斜杠将导致更频繁地调用// === Critical line ===
。
这有影响,因为事件被发射得很少,因为它对我没有任何用处(在已注释掉的情况下)
问题是,我无法在lv_LayoutUpdated
的突变结束之前设置滚动位置。然而,通过ScrollViewer
事件的路由似乎很愚蠢。
这是一个错误还是可以解释冒泡策略或某事?
编辑:顺便说一句,这个页面没有显示在应用程序的根框架中,但是在不同页面的框架中显示,如果这有任何区别。
EDIT2:我最终解决了为什么发射时间毫无用处(正在进行数据绑定异步,这与标准事件时序相关)。但是这种行为仍然存在 - 订阅ScrollViewer
的事件会导致更多ScrollViewer
事件的发布。在最终发生的其他情况下,我不知道。我正在使用Caliburn.Micro - 所以他们的数据源接线可能会对控件产生影响。
例如。 CM的一个问题是,它吞下了视图的第一个LayoutUpdated事件(如果通过Message:Attach toleast绑定) - 尽管这可能只会影响视图模型。
无论如何,我会把这个问题留给其他人来解决。
代码隐藏中的此设置:
ListView
XAML:
public FileListView()
{
this.InitializeComponent();
var lv = (ListView)FindName("Files");
lv.Loaded += lv_Loaded;
lv.LayoutUpdated += lv_LayoutUpdated;
}
void lv_LayoutUpdated(object sender, object e)
{
var m = (FileListViewModel)DataContext;
m.Offset = 100;
}
void lv_Loaded(object sender, RoutedEventArgs e)
{
var lv = (ListView)sender;
var sv = lv.GetFirstDescendantOfType<ScrollViewer>();
if (sv == null)
{
return;
}
//sv.LayoutUpdated += sv_LayoutUpdated; // === Critical line ===
}
void sv_LayoutUpdated(object sender, object e)
{
// No code here. Just the subscription suffices
}