我最近编写了一个 VirtualizingWrapPanel 的实现,它在容器滚动进出视图时回收容器。
有时我注意到控件呈现的内容实际上是先前包含的数据,而不是当前数据。对控件执行任何强制执行新渲染调用的操作都会更新控件,使其显示正确的数据。
这可能是 ItemContainerGenerator 回收中的错误,还是我的回收代码中更有可能?有没有一种方法可以强制更新所有绑定(在使用新内容更新控件之后),而无需在后面的代码中显式编写每个绑定表达式?
我最近编写了一个 VirtualizingWrapPanel 的实现,它在容器滚动进出视图时回收容器。
有时我注意到控件呈现的内容实际上是先前包含的数据,而不是当前数据。对控件执行任何强制执行新渲染调用的操作都会更新控件,使其显示正确的数据。
这可能是 ItemContainerGenerator 回收中的错误,还是我的回收代码中更有可能?有没有一种方法可以强制更新所有绑定(在使用新内容更新控件之后),而无需在后面的代码中显式编写每个绑定表达式?
过去在使用虚拟化时,当我们使用自定义控件时,我曾见过非常类似的问题,这些控件真的不希望它们的 DataContexts 在显示后被更改。
如果您的面板正确(听起来)将新的 DataContexts 传递给重用的对象,那么听起来重用的对象没有正确处理 DataContext 更改。(您所说的这个“渲染”调用将获取新的 DataContext 并显示它。)
如果您在控件中使用普通数据绑定,那么我有点难过。(您的面板是否在获得新的 DataContext 后重新测量/排列控件?)
我们的解决方法是让我们的控件监听它们的 DataContext 何时更改。(这对于调试虚拟化面板以测试 DataContext 是否正确输入也很有用。)
遗憾的是 OnDataContextChanged 方法在 Silverlight 中不公开,但您仍然可以通过绑定到 DC 更改来了解它们。
public MyClass()
{
InitializeComponent();
SetBinding(MyDataContextProperty, new Binding());
}
private static readonly DependencyProperty MyDataContextProperty =
DependencyProperty.Register("MyDataContext",
typeof(object),
typeof(MyClass),
new PropertyMetadata(DataContextChanged));
private static void DataContextChanged(
object sender,
DependencyPropertyChangedEventArgs e)
{
MyClass source = (MyClass)sender;
source.OnDataContextChanged();
}
private void OnDataContextChanged()
{
// My DataContext has changed; do whatever is needed.
// re 'render' in your case?
}