如何用多线程的两种实现方式方式同时实现ListBox的滚动功能

wpf listbox 滚动翻页功能 - bornonew的博客 - CSDN博客
wpf listbox 滚动翻页功能
最近有个需求,需要通过 listbox滚动实现翻页功能。查了下资料 总结如下。
方案一:利用ScrollViewer.ScrollChanged事件来实现当偏移量到底部时,进行相应操作。
&ListBox BorderBrush=&Red& Grid.Column=&0& ItemsSource=&{Binding SchoolNoticeList}& ItemTemplate=&{StaticResource listboxitemT}& ScrollViewer.ScrollChanged=&ListBox_ScrollChanged&/&
对应的事件
private void ListBox_ScrollChanged(object sender, ScrollChangedEventArgs e)
ScrollViewer sv = e.OriginalSource as ScrollV
ListScrollWndViewModel vm = this.DataContext as ListScrollWndViewM
if (sv != null)
Console.WriteLine(e.VerticalOffset.ToString());
if(IsVerticalScrollBarAtButtom(sv))
vm.MsgTest = &已到底部&;
vm.MsgTest=&未到底部&;
public bool IsVerticalScrollBarAtButtom(ScrollViewer s)
bool isAtButtom =
double dVer = s.VerticalO
double dViewport = s.ViewportH
double dExtent = s.ExtentH
Console.WriteLine(&dVer:&+dVer+& dViewport:&+dViewport+& dExtent:&+dExtent);
if (dVer != 0)
if (dVer + dViewport == dExtent)
isAtButtom =
isAtButtom =
isAtButtom =
if (s.VerticalScrollBarVisibility == ScrollBarVisibility.Disabled
|| s.VerticalScrollBarVisibility == ScrollBarVisibility.Hidden)
isAtButtom =
return isAtB
}按照微软(/zh-cn/library/ms612678)的解释&
VerticalOffset是获取包含滚动内容的垂直偏移量的值。,viewportheight是获取包含内容视区垂直大小的值。ExtentHeight&获取包含盘区垂直大小的一个值。
利用图来解释一下
这是一个20个数据长度(从0到20)长度的listbox,可以看出VerticalOffset其实就是从上往下覆盖的元素数量(4),viewportheight是控件可供人看到的元素数量(10=13-4+1) ExtentHeight是总的元素数量(20)。通过改变窗口大小,viewportheight会跟随改变,拖动滚动条,VerticalOffset也会跟着改变。判断滚动到底部的条件 自然就是
VerticalOffset+viewportheight==ExtentHeight
但这种方式 有两个问题
一个是如何向前翻页,如果简单的以VerticalOffset==0 来判断,当初始化的时候,就会发现scorllchanged就会触发,并且VerticalOffset等于0
二是当最后一页数据较少,滚动条不出现时,scorllchanged就永远不会被触发,也就是说最后一页无法向前翻。
直接利用previewmousewheel来判断向前向后翻转。
&ListBox BorderBrush=&Green& Grid.Column=&1& ItemsSource=&{Binding SchoolNoticeList}& ItemTemplate=&{StaticResource listboxitemT}& PreviewMouseWheel=&ListBox_PreviewMouseWheel& /&
对应的响应事件
private void ListBox_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
ListScrollWndViewModel vm = this.DataContext as ListScrollWndViewM
Console.WriteLine(e.Delta);
if (e.Delta & 0)
Console.WriteLine(&正在向上滚动滑轮&);
vm.MsgTest = &正在向上滚动滑轮&;
Console.WriteLine(&正在向下滚动滑轮&);
vm.MsgTest = &正在向下滚动滑轮&;
这种方法的劣势在于页面上数据不能太多(不能出现滚动条),否则被覆盖的数据不会显现出来。
把两种结合起来,也许会更好,利用previewmousewheel来触发事件,当滚动条偏移量为0,则向上翻页,滚动条到底部则 向下翻页。
首先需要获得listbox中的scrollviewer
Decorator border = VisualTreeHelper.GetChild(listbox3, 0) as D
if (border != null)
scrollViewer = border.Child as ScrollV
}然后在previewmousewheel里面进行事件处理
private void ListBox3_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
ListScrollWndViewModel vm = this.DataContext as ListScrollWndViewM
Console.WriteLine(e.Delta);
if (e.Delta & 0)
if (scrollViewer.VerticalOffset == 0)
if (scrollViewer.VerticalOffset + scrollViewer.ViewportHeight == scrollViewer.ExtentHeight)
scrollViewer.ScrollToTop();
我的热门文章
即使是一小步也想与你分享安全检查中...
请打开浏览器的javascript,然后刷新浏览器
< 浏览器安全检查中...
还剩 5 秒&今天看啥 热点:
在ListBox中添加一条记录(ListBox.Items.Add方法)后,滚动条会自动回到顶部。我们可能更希望它自动滚动到底部,本文简要介绍几种方法。 方法一:
this.listBox1.Items.Add(&new line&);&
this.listBox1.SelectedIndex = this.listBox1.Items.Count - 1;&
this.listBox1.SelectedIndex = -1;
在添加记录后,先选择最后一条记录,滚动条会自动到底部,再取消选择。
缺点是需两次设置选中条目,中间可能会出现反色的动画,影响美观。
this.listBox1.Items.Add(&new line&);
this.listBox1.TopIndex = this.listBox1.Items.Count - (int)(this.listBox1.Height / this.listBox1.ItemHeight);
通过计算ListBox显示的行数,设置TopIndex属性(ListBox中第一个可见项的索引)而达到目的。
方法二 plus:智能滚动
bool scroll =&
if(this.listBox1.TopIndex == this.listBox1.Items.Count - (int)(this.listBox1.Height / this.listBox1.ItemHeight))&
&this.listBox1.Items.Add(&new line&);&
if (scroll)
&this.listBox1.TopIndex = this.listBox1.Items.Count - (int)(this.listBox1.Height / this.listBox1.ItemHeight);
在添加新记录前,先计算滚动条是否在底部,从而决定添加后是否自动滚动。
相关搜索:
相关阅读:
相关频道:
&&&&&&&&&&&&&&&&
Asp.Net教程最近更新本帖子已过去太久远了,不再提供回复功能。1、添加listbox设置horizontal scroll为true
2、新建类CNListBox,继承类CListBox
3、新类头文件声明如下:
#ifndef _IHLISTBOX_H_#define _IHLISTBOX_H_
class CNListBox: public CListBox{
.......public:
int AddString( LPCTSTR lpszItem );int InsertString( int nIndex, LPCTSTR lpszItem );
void RefushHorizontalScrollBar( void );
4、新类cpp文件代码如下
int CNListBox::AddString( LPCTSTR lpszItem ){int nResult = CListBox::AddString( lpszItem );
RefushHorizontalScrollBar();
return nR}
int CNListBox::InsertString( int nIndex, LPCTSTR lpszItem ){int nResult = CListBox::InsertString( nIndex, lpszItem );
RefushHorizontalScrollBar();
return nR}
void CNListBox::RefushHorizontalScrollBar( void ){CDC *pDC = this-&GetDC();if ( NULL == pDC ){&&&}
int nCount = this-&GetCount();if ( nCount & 1 ){&&&this-&SetHorizontalExtent( 0 );&&&}
int nMaxExtent = 0;CString szTfor ( int i = 0; i & nC ++i ){&&&this-&GetText( i, szText );&&&CSize &cs = pDC-&GetTextExtent( szText );&&&if ( cs.cx & nMaxExtent )&&&{&&&&nMaxExtent = cs.&&&}}
this-&SetHorizontalExtent( nMaxExtent );}
5、可以在其他文件中使用该类
CPP文件中引用如下头文件
#include "NListBox.h"#define LIST ((CNListBox* )(GetDlgItem(IDC_Point)))
添加字段代码如下:
LIST-&AddString( _T("") );
阅读(...) 评论()

我要回帖

更多关于 线程两种实现方式 的文章

 

随机推荐