wpf listbox 滚动翻页功能

最近有个需求,需要通过 listbox滚动实现翻页功能。查了下资料 总结如下。

代码: 点击打开链接

方案一:利用ScrollViewer.ScrollChanged事件来实现当偏移量到底部时,进行相应操作。

xaml中

  <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 ScrollViewer;
            ListScrollWndViewModel vm = this.DataContext as ListScrollWndViewModel;
            if (sv != null)
            {
                Console.WriteLine(e.VerticalOffset.ToString());
                if(IsVerticalScrollBarAtButtom(sv))
                {             
                    vm.MsgTest = "已到底部";
                }
                else{
                    vm.MsgTest="未到底部";
                
                }
            }
        }

        public bool IsVerticalScrollBarAtButtom(ScrollViewer s)
        {

            bool isAtButtom = false;
            double dVer = s.VerticalOffset;
            double dViewport = s.ViewportHeight;
            double dExtent = s.ExtentHeight;
            Console.WriteLine("dVer:"+dVer+" dViewport:"+dViewport+" dExtent:"+dExtent);
            if (dVer != 0)
            {
                if (dVer + dViewport == dExtent)
                {
                    isAtButtom = true;
                }
                else
                {
                    isAtButtom = false;
                }
            }
            else
            {
                isAtButtom = false;
            }
            if (s.VerticalScrollBarVisibility == ScrollBarVisibility.Disabled
                || s.VerticalScrollBarVisibility == ScrollBarVisibility.Hidden)
            {
                isAtButtom = true;
            }
            return isAtButtom;
        }
按照微软(https://msdn.microsoft.com/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来判断向前向后翻转。

xaml

            <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 ListScrollWndViewModel;
            Console.WriteLine(e.Delta);
            if (e.Delta > 0)
            {
                Console.WriteLine("正在向上滚动滑轮");
                vm.MsgTest = "正在向上滚动滑轮";
            }
            else
            {
                Console.WriteLine("正在向下滚动滑轮");
                vm.MsgTest = "正在向下滚动滑轮";
            }
        }

这种方法的劣势在于页面上数据不能太多(不能出现滚动条),否则被覆盖的数据不会显现出来。


把两种结合起来,也许会更好,利用previewmousewheel来触发事件,当滚动条偏移量为0,则向上翻页,滚动条到底部则 向下翻页。

首先需要获得listbox中的scrollviewer

   Decorator border = VisualTreeHelper.GetChild(listbox3, 0) as Decorator;
            if (border != null)
            {
                scrollViewer = border.Child as ScrollViewer;               
            }
然后在previewmousewheel里面进行事件处理

  private void ListBox3_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            ListScrollWndViewModel vm = this.DataContext as ListScrollWndViewModel;
            Console.WriteLine(e.Delta);
            if (e.Delta > 0)
            {
                if (scrollViewer.VerticalOffset == 0)
                {
                    Pre();                }
            }
            else
            {
                if (scrollViewer.VerticalOffset + scrollViewer.ViewportHeight == scrollViewer.ExtentHeight)
                {
                    Next();
                    scrollViewer.ScrollToTop();
                }
            }
        }






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值