需求
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到底移动多少的问题。
写了个最简单的策略,没来两条新数据,向下滚动一行。基本上保证了所选的数据,不会脱离可视区域。
还有点不足的就是因为每行是两个,来了新数据会导致,你看的那个数据会左右摆动。