UWP VirtualizedVariableSizedGridView 支持可虚拟化可变大小Item的View(一)
Boss的需要时这样的,Item是可变大小的,同时根据不同的Window size,来确定Item的结构和大小
Window 小的时候是
大的时候是这样的:

当然这size变化的过程中也允许其他结构,我这里只是举了最大和最小时候的样子。
当拿到需求的时候,相信大家肯定第一想到的是,将GirdView的ItemsPanel改成VariableSizedWrapGrid。
VariableSizedWrapGrid是怎么样用的,不知道的童鞋点击先行脑补下.官方文档 diederik的sample
嗯,效果就这样的,差不多。。。是这样的吗??
仔细的朋友可以看到了这段话:
The content of a VariableSizedWrapGrid is not virtualized. This can reduce performance when you work with large data sets. For more info, see Optimize ListView and GridView.
哦,no。这个东西不支持虚拟化。。
Google了下,嗯。各种网上问的,但是没有解决办法。想想也是,这种结构,是很难计算出Items的总高度或者总宽度的。
本着我不下地狱谁下地狱的原则,既然没人搞出来,就让我来造福大众吧。。。我疯狂的上网搜索,自己也想过一些办法,但都被自己推倒了。(太软,易推倒)
吃晚饭的时候突然灵光一现,嗯,想出了下面的结构:
ListView的每个Item是个GridView,而将GirdView的ItemsPanel改成VariableSizedWrapGrid。
自己写了个简单的sample,稍微搞了些,可行。
数据结构应该是这样的:
比如一共有150个Item,15个元素为一组作为每个GridView的源来组成可变大小结构。
现在的问题来了,怎么样才能方便的把原始的数据结构转变为我想要的那种呢??
方法是写一个IList 类来做这个分割。
internal class RowAdapter<T> : IList<IEnumerable<T>>, ISupportIncrementalLoading
{
private readonly IList<T> items;
public readonly int rowItemsCount; public IList<T> SourceList
{
get { return items; }
} public RowAdapter(IList<T> sourceList, int rowItemsCount)
{
if (null == sourceList)
throw new ArgumentNullException("sourceList", "sourceList can not be null");
if (rowItemsCount <= )
throw new ArgumentOutOfRangeException("rowItemsCount", "rowItemsCount should be more than one"); // We require the source list to implement IList because we
// need to know how many item there are
items = sourceList;
this.rowItemsCount = rowItemsCount; } #region IList<IEnumerable<T>> Members public int IndexOf(IEnumerable<T> item)
{
var realItem = item as RowObject<T>;
if (null == realItem || !ReferenceEquals(realItem.Parent, this))
return -; // It does not belong to this collection Debug.Assert( == realItem.StartIndex % rowItemsCount, "RowObject item has a wierd index");
return realItem.StartIndex / rowItemsCount;
} public void Insert(int index, IEnumerable<T> item)
{
throw new NotSupportedException();
} public IEnumerable<T> 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<T>> Members public void Add(IEnumerable<T> item)
{
throw new NotSupportedException();
} public bool Contains(IEnumerable<T> item)
{
var realItem = item as RowObject<T>;
return null != realItem && object.ReferenceEquals(realItem.Parent, this);
} public void CopyTo(IEnumerable<T>[] array, int arrayIndex)
{
// I haven't implemented this. It is easy to implement if you need it
throw new NotImplementedException();
} public bool Remove(IEnumerable<T> item)
{
throw new NotSupportedException();
}
public void Clear()
{
throw new NotSupportedException();
} public int Count
{
get
{
return (items.Count + (rowItemsCount - )) / rowItemsCount;
}
} public bool IsReadOnly
{
get { return true; }
} public bool HasMoreItems
{
get
{
if (items is ISupportIncrementalLoading)
{
return (items as ISupportIncrementalLoading).HasMoreItems;
}
return false;
}
} #endregion #region IEnumerable<IEnumerable<T>> Members public IEnumerator<IEnumerable<T>> 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 private RowObject<T> InternalGetRow(int index)
{
return new RowObject<T>(this, index * rowItemsCount);
} public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
{
if (items is ISupportIncrementalLoading)
{
IAsyncOperation<LoadMoreItemsResult> result = (items as ISupportIncrementalLoading).LoadMoreItemsAsync(count);
return result;
} return null;
}
}
可以看到这个类的构造
public RowAdapter(IList<T> sourceList, int rowItemsCount)
sourceList就是源数据,而rowItemsCount就是每个GirdView里面源的个数。
到这里我们就解决了,整个控件的大体思路以及源的处理,下一篇会讲讲该开发中一些重要问题的解决。
有问题的朋友可以留言,或者查看GitHub源码
UWP VirtualizedVariableSizedGridView 支持可虚拟化可变大小Item的View(一)的更多相关文章
- UWP VirtualizedVariableSizedGridView 支持可虚拟化可变大小Item的View(二)
上篇UWP VirtualizedVariableSizedGridView 支持可虚拟化可变大小Item的View(一) 讲到该控件的需要和设计过程. 这篇讲讲开发过程中一些重要问题解决. 1.支持 ...
- 算法Sedgewick第四版-第1章基础-008一用数组实现栈(泛型、可变大小)
package algorithms.ADT; /*************************************************************************** ...
- Xamarin.Forms 现已开启对 UWP 的支持
Xamarin.Forms 现已升级到 2.0.0.6482 , 正式开启了对 UWP 的支持. 要创建 UWP 项目, 必须是 VS2015, WIN8.1 下也可以, 但是只有 Windows 1 ...
- 关于理解《C++ 对象模型》中:把单一元素的数组放在末尾,struct可以拥有可变大小的数组
这一章在第19页,写的好深奥,我竟然没看明白在说什么--之后再看了几遍,终于明白了. 原文: C程序员的巧计有时候却成为c++程序员的陷阱.例如把单一元素的数组放在一个struct的末尾,于是每个st ...
- 64位平台支持大于2 GB大小的数组
64位平台支持大于2 GB大小的数组 64位平台.NET Framework数组限制不能超过2GB大小.这种限制对于需要使用到大型矩阵和向量计算的工作人员来说,是一个非常大问题. 无论RAM容量有多大 ...
- 移动设备应用程序中支持多个屏幕大小和 DPI 值
支持多个屏幕大小和 DPI 值的指导原则 要部署独立于平台的应用程序,应了解不同的输出设备.设备可以具有不同的屏幕大小或分辨率以及不同的 DPI 值或密度. Flex 工程师 Jason SJ 在他的 ...
- 使struct对象拥有可变大小的数组——(C++深度探索)
首先摘录<Inside The C++ Object Model>中的一段话: 把单一元素的数组放在一个struct的尾端,于是每个 struct objects 可以拥有可变大小的数组: ...
- 0x04 Python logger 支持多进程日志按大小分割
目录 支持多进程日志按大小分割 多进程日志大小分割handler配置实例 支持多进程日志按大小分割 由于python内置模块logging.handlers.RotatingFileHandler是不 ...
- 如何查看自己的电脑 CPU 是否支持硬件虚拟化
引言 在你安装各种虚拟机之前,应该先测试一下自己的电脑 CPU 是否支持硬件虚拟化. 如果你的电脑比较老旧,可能不支持硬件虚拟化,那么将无法安装虚拟机软件. 如何查看自己 CPU 是否支持硬件虚拟化 ...
随机推荐
- [Java] Spring MVC 知识点
云图: @Service 用于标注业务层组件. 在 Spring-servlet 配置xml中,component-scan 标签默认情况下自动扫描指定路径下的包(含所有子包),将带有@Compone ...
- git误删文件找回方法/git版本回退方法
使用git命令 git rm css/\*.css 我删掉了css文件夹下所有以.css结尾的文件,那么要怎样才能把文件找回来呢,下面说说方法,删掉其他的文件也是一样的方式找回. 第一步:使用git ...
- MySQL练习-employees数据库(一)
安装一个数据库示例--employees 使用工具为Navicat--(ctrl + q: 打开新查询窗口 ctrl + r: 运行当前窗口内的所有语句) 参考http://www.cnblogs.c ...
- 遍历Map的方法
1.使用 entrySet() entrySet() --> 官方推荐将Map转换成Map.Entry对象的Set集合 Set entrys = map.entrySet(); Iterat ...
- JS阻止冒泡事件以及默认事件发生的简单方法
如果<p>是在<div>里面,那么呢,<P>有一个onclick事件,<div>也有onclick事件,为了触发<P>的点击事件时,不触发父 ...
- fzf by ruby
fzf by ruby */--> fzf by ruby 1 github地址 https://github.com/junegunn/fzf 2 简介 软件通过匿名管道和grep扩展了bas ...
- easyUI中onLoadSuccess方法获取多个对象
后台将一个list中的对象循环放到map中,如下: @RequestMapping("/getSaleOrderDetailList") @ResponseBody public ...
- springmvc拦截器验证登录时间
在前一篇[Filter实现用户名验证]的随笔里,记录了如何使用filter 这次增加了拦截器实现 ①filter实现用户登陆时验证用户名是否为null ②interceptor实现用户登陆时时间判断, ...
- Docker - 技术栈
与传统的方式类似,构建及运行Docker容器与在一台虚拟机上构建和运行程序的方式是相似的,只是使用了一套新的工具以及技术. 与虚拟机不同的是,Docker容器将宿主机与应用程序或者服务隔离,从而提高了 ...
- xpath定位中starts-with、contains和text()的用法
starts-with 顾名思义,匹配一个属性开始位置的关键字 contains 匹配一个属性值中包含的字符串 text() 匹配的是显示文本信息,此处也可以用来做定位用 eg //input[sta ...