wpf 滚动条的相对静止

需求

1.新消息到来,插在队首,消息最多显示100条

2.每行显示两列新消息

3.当用户拖动滚动条时,或点击某条消息时,会在当前显示页面静止。如果此时有新消息来,10s后,跳到队首,否则一直保持在当前页。

实现

1.消息保存至ObservableCollection,显示用Listview,将两者绑定在一起,这样来了新消息,如果队列的长度大于100就从队尾删除一个元素,

然后将新消息插入到ObservableCollection队首。Listview也会相应变化。

插入用ObservableCollection.Insert()

删除用ObservableCollection.RemoveAt()

如果想要看删除的元素

则用ObservableCollection.ElementAt()获取

然后用ObservableCollection.Remove()去删除

2.每行显示两列消息,通过设置ListView.ItemsPanel 为wrapPanel ,ListView宽度,消息的显示宽度来设置。保证每行的宽度正好为两个放的下,三个放不下。这样WrapPanel就自动帮助你两个换行。

     <ListView Name="recordList" Grid.Row="1" BorderThickness="0" PreviewMouseDown="recordList_PreviewMouseDown" PreviewMouseUp="recordList_PreviewMouseUp" >
            <ListView.Template>
                <ControlTemplate>
                    <ScrollViewer    Name="scrollViewer" CanContentScroll="True"  PreviewMouseWheel="scrollViewer_PreviewMouseWheel">
                        <ItemsPresenter />
                    </ScrollViewer>
                </ControlTemplate>
            </ListView.Template>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <local:WrapPanelWithScroll Background="#b6cce0"  x:Name="wrapPanel1"  >


                    </local:WrapPanelWithScroll>
                    <!--<WrapPanel Background="#b6cce0" >


                    </WrapPanel>-->
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>

3.第三个需求,有些麻烦。

思路是弄两个标志位,isScroll和isNewData. 分别记录是否允许滚动条滚动,和是否有新数据。

每次来新消息,先把isNewData置为真,然后判断isScroll,为真就调用ScrollToTop(),并且把isNewData置为false,假就什么都不做。

建一个10s的定时器,来记录滚动事件触发时间,到10,通过isNewData是否为真,为真则滚动到队首。

接下来就是如何触发时间。

分两块

 一个是用鼠标滚轮操作滚动条,

PreviewMouseWheel事件,每次滚动都把定时器置0.

二是用鼠标操作滚动条(用鼠标拖动,以及点击上下按钮)

PreviewMouseDown时,把isScroll置为false。
PreviewMouseUp时,把定时器置0

做完这些,你会发现,虽然滚动条不动了,但是由于来了新数据都会插到队首,数据其实是一直往下走的,滚动条相对于数据来说还是动了的。

最简单的思路,滚动时,数据并不仅队列,而进入一个额外队列,10s到了之后,在入队。缺点是如果一直滚动,新数据就一直不会显示。老大不同意这么做。

另外一种思路就需要进行额外的计算,当数据来时,滚动条向下滚动一个合适的距离。

查了一些方法,最合适的就是scrollviewer的lineup和linedown.但有个问题,默认的scrollviewer都是物理滚动,也就是说滚动的是一个偏移量,(而这个偏移量offset怎么改我没找到),还有一种是逻辑滚动,就是每次滚一个项的距离,用<ScrollViewer CanContentScroll="True">来控制何种滚动方式,很遗憾直接加上了,并不管用。

后来参考了 这篇文章,http://www.cnblogs.com/TianFang/p/4198731.html

重做一个WrapPanelWithScroll控件,基本上实现了这个功能。这个控件本质上,就是手动控制,offset到底移动多少的问题。

写了个最简单的策略,没来两条新数据,向下滚动一行。基本上保证了所选的数据,不会脱离可视区域。

还有点不足的就是因为每行是两个,来了新数据会导致,你看的那个数据会左右摆动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值