Den*_*inh 7 c# wpf listview event-handling scrollviewer
我的目标是在WPF中模拟"无限滚动" ListView
.我用一些不太理想的方法完成了这项任务,我确信有更好的方法.
通过"无限滚动"我的意思是:
让我们说一个ListView
有20个项目(有序1, 2, 3, 4, ... 17, 18, 19, 20
).当用户向下滚动一个项目时,该项目顶部的项目ListView
被移除并放置在项目的结尾处,ListView
因此项目的顺序是2, 3, 4, 5, ... 18, 19, 20, 1
.现在,如果用户向下滚动两个项目,则前两个项目将被移除并放置在最后,因此项目的顺序为4, 5, 6, 7, ... 20, 1, 2, 3
.现在,类似地,如果用户向上滚动一个项目,则将其底部的项目ListView
移除并放置在开头,以便项目的顺序为3, 4, 5, 6, ... 19, 20, 1, 2
.
我已经实现这个任务与分配给下面的功能ScrollChanged
的情况下,ScrollViewer
我希望是"无限":
// sv - the ScrollViewer to which this event handler is listening
// lv - the ListView associated with "sv"
bool handle_scroll = true;
private void inf_scroll(object sender, ScrollChangedEventArgs e) {
if (handle_scroll) {
for (int i = 0; i < e.VerticalChange; i++) {
object tmp = lv.Items[0];
lv.Items.RemoveAt(0);
lv.Items.Add(tmp);
handle_scroll = false;
}
for (int i = 0; i > e.VerticalChange; i--) {
object tmp = lv.Items[lv.Items.Count - 1];
lv.Items.RemoveAt(lv.Items.Count - 1);
lv.Items.Insert(0, tmp);
handle_scroll = false;
}
if(!handle_scroll){
sv.ScrollToVerticalOffset(sv.VerticalOffset - e.VerticalChange);
}
}
else {
handle_scroll = true;
}
}
Run Code Online (Sandbox Code Playgroud)
注意变量handle_scroll
.我把它放到位是因为调用sv.ScrollToVerticalOffset
将导致整个inf_scroll
函数被递归调用,如果不存在的话.
我知道滚动ScrollViewer
一个ScrollChanged
事件处理程序是不好的做法,所以这就是我要问的原因:有更好的方法吗?如何防止递归调用inf_scroll
?有没有更好的方法来模拟"无限滚动"?
尽管它没有明确避免在ScrollChanged
处理程序中滚动,但您可以尝试以下操作:
// sv - the ScrollViewer to which this event handler is listening
// lv - the ListView associated with "sv"
private void inf_scroll(object sender, ScrollChangedEventArgs e) {
for (int i = 0; i < e.VerticalChange; i++) {
object tmp = lv.Items[0];
lv.Items.RemoveAt(0);
lv.Items.Add(tmp);
}
for (int i = 0; i > e.VerticalChange; i--) {
object tmp = lv.Items[lv.Items.Count - 1];
lv.Items.RemoveAt(lv.Items.Count - 1);
lv.Items.Insert(0, tmp);
}
lv.ScrollChanged -= inf_scroll; // remove the handler temporarily
sv.ScrollToVerticalOffset(sv.VerticalOffset - e.VerticalChange);
Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() =>{
sv.ScrollChanged += inf_scroll; // add the handler back after the scrolling has occurred to avoid recursive scrolling
}));
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
622 次 |
最近记录: |