最近项目中遇到加载数据的性能问题, 原因是.net4.0的虚拟化支持不够完成,有好多bug在4.5才修复。 我们只能利用大家通用的做法来延迟加载数据:
每次加载固定少量的数据,当拖动到底后,继续加载后续相同数量的数据。
思路:
监听ScrollViewer的VerticalOffsetProperty,如果值达到允许滚动的高度ScrollableHeight,则发出event通知外部处理加载逻辑。
使用方法:
1.对于ItemsControl编辑控件模板,在其中的ScrollViewer中加入behavior。
<ScrollViewer x :Name="DG_ScrollViewer" Focusable="false">
<i: Interaction.Behaviors>
<local: ReachingBottomBehavior ReachingBottomEvent="LazyLoadingBehavior_OnReachingBottomEvent" />
</i: Interaction.Behaviors>
在blend中,比较简单,直接对控件右键,编辑模板/副本,进入ScrollViewer后,把这个behavior拖到ScrollViewer的元素下即可, 生成的代码就是上面的内容。
xmlns:i ="http://schemas.microsoft.com/expression/2010/interactivity"
2.实现上面ReachingBottomEvent的处理逻辑。比如:
private void LazyLoadingBehavior_OnReachingBottomEvent ()
{
var vm = LayoutRoot. DataContext as MainViewModel;
if (vm != null)
{
int count = dtgRoot. Items .Count ;
for (int i = count ; i < count + 30; i ++)
{
vm .DataItems . Add(
new DataItem ()
{
Item1 = i . ToString(),
Item2 = i . ToString() + i .ToString ()
});
}
}
}
代码如下:
public class ReachingBottomBehavior : Behavior< ScrollViewer>
{
public ReachingBottomBehavior ()
{
// Insert code required on object creation below this point.
}
protected override void OnAttached()
{
base.OnAttached ();
// Insert code that you would want run when the Behavior is attached to an object.
var dpd = DependencyPropertyDescriptor. FromProperty(ScrollViewer .VerticalOffsetProperty, AssociatedType);
dpd.AddValueChanged (
AssociatedObject,
(sender,
args) =>
{
RaiseReachingBottomEvent();
});
}
protected override void OnDetaching()
{
base.OnDetaching ();
// Insert code that you would want run when the Behavior is removed from an object.
}
private void RaiseReachingBottomEvent()
{
bool isReachingBottom = AssociatedObject. VerticalOffset >= AssociatedObject .ScrollableHeight;
if (isReachingBottom )
{
if (this .ReachingBottomEvent != null)
{
this.ReachingBottomEvent ();
}
}
}
public event Action ReachingBottomEvent;
}