windows phone listbox虚拟化(下)
之前写过一篇关于listbox虚拟化的文章,那里采用的方法都是自己早期研究的一些思路,然后发现当数据很大的时候,其实性能效果还是不太理想,下面让我们来仔细想一想到底是基于什么原因,我们回去破坏默认的虚拟化呢?首先一个原因就是下来刷新的问题:由于listbox默认是不支持刷新效果的,这个时候我们可能回去重新自定义listbox,但是我们一旦重写listbox就有可能带来虚拟化的问题,针对这一问题,现在比较好的解决方法就是:乱世经典博客,这种方法并不是像现在很多网路通用的listbox刷新,重写三个自定义控件,它里面只是通过切换不同的VisualStateGroup,这样的话listbox的itemplans就还是支持虚拟化的面板。既然刷新的问题,我们有很好的办法解决虚拟化。那么还有其他的原因会让我们破坏虚拟化吗?肯定是有的,就是当整个页面列表的布局很复杂时候,这种情况下我们可能需要在listbox里面放置自定义控件,一旦你放置usercontrol的话,虚拟化就被破坏了,比如有的时候,我们可能需要listbox里面嵌套listbox这个时候虚拟化肯定是不行的,其实这种情况也有一种很好的解决办法就是:阿干@.NET的博客,在这里面我们可以看到针对listbox里面嵌套listbox的情况,我们可以使用itemcontrols,这样一来的话,它的itempanels就还是虚拟化面板,因此虚拟化还是没有被破坏掉的。
其实还有一种变态的情况就是有的时候我们需要listbox显示的数据是横排的,通常我们的做法就是:
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel></toolkit:WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
这样一来的话,就必然会导致虚拟化被破坏,因为你连面板都换掉了。那么针对这种情况有没有好的解决办法呢?其实阿干那篇博客里面就提供了好的解决办法,我们可以自己去实现分列显示的效果,核心的代码是:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics; namespace MoHoo.MultiColumnListBox.Demo
{
public class RowAdapter<TItemType> : IList<IEnumerable<TItemType>>, INotifyCollectionChanged
{
private readonly IList<TItemType> _sourceList;
private readonly int _columns; public IList<TItemType> SourceList
{
get { return _sourceList; }
} private class RowObject : IEnumerable<TItemType>
{
internal readonly RowAdapter<TItemType> Parent;
internal readonly int StartIndex; public RowObject(RowAdapter<TItemType> parent, int startIndex)
{
Parent = parent;
StartIndex = startIndex;
} #region IEnumerable<TItemType> Members public IEnumerator<TItemType> GetEnumerator()
{
int limit = Parent._sourceList.Count;
int end = Math.Min(StartIndex + Parent._columns, limit); for (int pos = StartIndex; pos < end; ++pos)
{
yield return Parent._sourceList[pos];
}
} #endregion #region IEnumerable Members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
} #endregion
} public RowAdapter(IList<TItemType> sourceList, int columns)
{
if (null == sourceList)
throw new ArgumentNullException("sourceList", "Resource.RowAdapter_RowAdapter_sourceList_is_null");
if (columns <= )
throw new ArgumentOutOfRangeException("columns", "Resource.RowAdapter_RowAdapter_ColumnsGreaterOne"); // We require the source list to implement IList because we
// need to know how many item there are
_sourceList = sourceList;
_columns = columns; var sourceNotify = sourceList as INotifyCollectionChanged;
if (null != sourceNotify)
{
sourceNotify.CollectionChanged += OnSourceCollectionChanged;
}
} #region IList<IEnumerable<TItemType>> Members public int IndexOf(IEnumerable<TItemType> item)
{
var realItem = item as RowObject;
if (null == realItem || !ReferenceEquals(realItem.Parent, this))
return -; // It does not belong to this collection Debug.Assert( == realItem.StartIndex % _columns, "RowObject item has a wierd index");
return realItem.StartIndex / _columns;
} public void Insert(int index, IEnumerable<TItemType> item) {
throw new NotSupportedException();
} public IEnumerable<TItemType> this[int index]
{
get
{
if (index < || index > Count)
return null; return InternalGetRow(index);
}
set
{
throw new NotSupportedException();
}
} public void RemoveAt(int index)
{
throw new NotSupportedException();
} #endregion #region ICollection<IEnumerable<TItemType>> Members public void Add(IEnumerable<TItemType> item)
{
throw new NotSupportedException();
} public bool Contains(IEnumerable<TItemType> item)
{
var realItem = item as RowObject;
return null != realItem && object.ReferenceEquals(realItem.Parent, this);
} public void CopyTo(IEnumerable<TItemType>[] array, int arrayIndex)
{
// I haven't implemented this. It is easy to implement if you need it
throw new NotImplementedException();
} public bool Remove(IEnumerable<TItemType> item)
{
throw new NotSupportedException();
}
public void Clear()
{
throw new NotSupportedException();
} public int Count
{
get
{
return (_sourceList.Count + (_columns - )) / _columns;
}
} public bool IsReadOnly
{
get { return true; }
} #endregion #region IEnumerable<IEnumerable<TItemType>> Members public IEnumerator<IEnumerable<TItemType>> GetEnumerator()
{
for (int i = ; i < Count; ++i)
{
yield return InternalGetRow(i);
}
} #endregion #region IEnumerable Members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
} #endregion #region INotifyCollectionChanged Members public event NotifyCollectionChangedEventHandler CollectionChanged; private void FireCollectionChanged()
{ var handler = CollectionChanged;
if (null != handler)
{
handler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
} private void OnSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
FireCollectionChanged();
} #endregion private RowObject InternalGetRow(int index)
{
return new RowObject(this, index * _columns);
}
}
}
这里面的核心思想就是自定义一个索引器。
windows phone listbox虚拟化(下)的更多相关文章
- Windows Phone Listbox虚拟化的问题
最近在项目里面碰到最头疼的一个难题就是Listbox虚拟化的问题,查阅很多文档其实Listbox本身是支持虚拟化的,那么在什么情况下会破坏Listbox的虚拟化呢?目前我接触到的主要有两个原因:一.是 ...
- Windows phone UI虚拟化和数据虚拟化(二)
书接上回的Windows phone UI虚拟化和数据虚拟化(一)我们学习了wp的ui虚拟化.今天来和大家分享一下wp的数据虚拟化. 并同时感谢我的同事dgwutao在编写此文时给我的巨大帮助,3ks ...
- Windows phone UI虚拟化和数据虚拟化(一)
今天和大家分享一些关于windows phone ui虚拟化和数据虚拟化的一些知识. 也顺便回答我上一篇[LongListSelector 控件 在 wp7 和wp8中的不同之处]里,留下的那个问题, ...
- Windows Server 2012 虚拟化实战:网络(二)
关于Windows Server的虚拟化网络,前文描述了在操作系统层面上的出现的配置变化.其中的一些配置通过Windows Server提供的小工具即可实现,如网卡组的配置,而有些需要安装Window ...
- Windows Server 2012 虚拟化实战:存储(二)
五.搭建Window Server 2012虚拟化的存储网络 前文我们讨论了Window Server 2012支持的各种与存储相关的技术,接下来我们通过实践对其中的一些技术进行检验.实际上Windo ...
- Windows Server 2012 虚拟化实战:存储(一)
在计算机世界我们随处可以见的一种方法,那就是抽象.1946年冯诺依曼提出了计算机的基本结构包含:计算器,存储器和I/O设备.这可能是对计算机这一新生事物最重要的一次抽象,它直接影响了今后几十年计算机软 ...
- Windows Server 2003 Sp2 下无法安装SQL Server 2008 Management Studio Express问题
Windows Server 2003 Sp2 下无法安装SQL Server 2008 Management Studio Express问题钉子 发表于 2010-5-22 1:42:51问题描述 ...
- Windows及Linux平台下的计时函数总结
本文对Windows及Linux平台下常用的计时函数进行总结,包括精度为秒.毫秒.微秒三种精度的各种函数.比如Window平台下特有的Windows API函数GetTickCount().timeG ...
- Thrift在Windows及Linux平台下的安装和使用示例
本文章也同时发表在个人博客Thrift在Windows及Linux平台下的安装和使用示例上. thrift介绍 Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的R ...
随机推荐
- wamp环境下外网访问自己电脑自己写的网站
首先我广州电信是对外封杀80端口的,但是内网可以用80端口访问, 可以将访问的端口改成81, apache的配置文件,httpd.conf 首先找到3个Listen 将80端口改成81 #Listen ...
- IE SEESION共享的问题
前几天,我们在开发工作流的过程中出现了一个比较奇怪的问题,原本看不到流程的人员,在登陆后却能够看到对应流程的待办任务,并且导致流程流向混乱!在调模式下调试程序发现(假设登陆两个用户)第二个登陆用户的信 ...
- C++临时变量的生命周期
C++ 中的临时变量指的是那些由编译器根据需要在栈上产生的,没有名字的变量.主要的用途主要有两类: 1) 函数的返回值, 如: string proc() { return string(" ...
- java web学习
一直想下决心好好学下java web,但是总是间断,虽然我的方向是ios,但是觉得后台也是相当重要,毕竟移动端实际上更多也就是展示后台拉取到的信息,搞移动端的不能总是受制于后台,各位看官觉得呢? 这两 ...
- CSS长度单位
罗列了CSS中常用的长度单位及比较 单位 含义 em 相对于父元素的字体大小 ex 相对于小写字母"x"的高度 rem 相对于根元素字体大小 px 相对于屏幕分辨率而不是视窗大小: ...
- sql语句小练习一
create database aaa go use aaa go create table student( sno varchar(3), sname varchar(4) not null ...
- 织梦dedecms中html和xml格式的网站地图sitemap制作方法
sitemap是网站上各网页的列表.创建并提交sitemap有助于百度(Google)发现并了解您网站上的所有网页,包括百度通过传统抓取方式可能找不到的网页.还可以使用sitemap提供有关你网站的其 ...
- 修改VS解决方案及工程名,解决如何打开高/版本VS项目
对于VS2008等低版本与高版本VS之间的转换问题: 对照下面2个版本的不同点自由修改,切换到相应的版本文件(红字修改,灰色删除) ---------------------------------- ...
- Linux:两台服务器之间添加信任关系,进行远程操作的时候不需要输入密码
两台机器之间建立信任关系的步骤: 1. 在机器1上root用户执行ssh-keygen命令,生成建立安全信任关系的证书,直接Enter [root@CentOS64-x64 ~]# ssh-keyge ...
- README.md
#gzq-h5app 本项目依赖于nodejs,请尽量安装最新版本. 需要先将Grunt命令行(CLI)安装到全局环境中.安装时可能需要使用sudo(针对OSX.*nix.BSD等系统中)权限或者作为 ...