最近项目中遇到加载数据的性能问题, 原因是.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
;
}