瀑布流已经有点年代了吧,不过wp上还真是挺少资料的。今天抽空把自己之前搞过的东西写出来,避免大家重复劳动。
一、简单的瀑布流排版加入ui虚拟化。
最近看了 段博琼 ui虚拟化的一篇博文,链接:http://www.cnblogs.com/hebeiDGL/p/3410575.html
觉得还不错,于是下载了他的demo稍微改了一下瀑布流效果。
demo截图如下:
主要改动:
1:自定义WaterFallPanel继承Panel,用于实现瀑布流排版,并保持容器children距离顶部高度的信息:
public class WaterFallPanel : Panel { public WaterFallPanel() { /**默认2列**/ ColumnCount = 2; ColumnHeight = new double[ColumnCount]; childwidth = 480 / ColumnCount; } double childwidth; static double[] ColumnHeight; /// <summary> /// 列数 /// </summary> public int ColumnCount { get { return (int)this.GetValue(ColumnCountProperty); } set { this.SetValue(ColumnCountProperty, value); } } public static DependencyProperty ColumnCountProperty = DependencyProperty.Register("WaterFallPanel", typeof(int), typeof(WaterFallPanel), new PropertyMetadata(new PropertyChangedCallback((o, e) => { ColumnHeight = new double[(int)e.NewValue]; if (o == null || e.NewValue == e.OldValue) return; o.SetValue(ColumnCountProperty, e.NewValue); }))); protected override Size MeasureOverride(Size availableSize) { Size resultSize = new Size(0, 0); //List<DependencyObject> Children = this.GetVisualChildren().ToList(); for (int i = 0; i < Children.Count; i++) { Children[i].Measure(availableSize); } #region 测量值 for (int i = 0; i < ColumnHeight.Count(); i++) { ColumnHeight[i] = 0; } heightlist.Clear(); for (int i = 0; i < Children.Count; i++) { double miniheight = ColumnHeight.Min(); int h = 0; for (; h < ColumnHeight.Length; h++) { if (ColumnHeight[h] == miniheight) { break; } } ColumnHeight[h] += Children[i].DesiredSize.Height; heightlist.Add(ColumnHeight.Min()); } #endregion resultSize.Height = ColumnHeight.Max(); if (Children.Count == 0) { resultSize.Height = 0; resultSize.Width = 480; } else { resultSize.Width = (Children.Count + 1) * Children[0].DesiredSize.Width; } return resultSize; } protected override Size ArrangeOverride(Size finalSize) { for (int i = 0; i < ColumnHeight.Count(); i++) { ColumnHeight[i] = 0; } #region 排列值 heightlist.Clear(); for (int i = 0; i < Children.Count; i++) { double miniheight = ColumnHeight.Min(); int h = 0; for (; h < ColumnHeight.Length; h++) { if (ColumnHeight[h] == miniheight) { break; } } Children[i].Arrange(new Rect(new Point(Children[i].DesiredSize.Width * h, ColumnHeight[h]), Children[i].DesiredSize)); ColumnHeight[h] += Children[i].DesiredSize.Height; if (h == 0) { if (Children[i].DesiredSize.Width > childwidth) { ColumnHeight[h + 1] += Children[i].DesiredSize.Height; } } heightlist.Add(ColumnHeight.Min()); } if (Children.Count < ColumnCount) finalSize.Width = childwidth * (Children.Count + 1); else finalSize.Width = childwidth * (ColumnCount + 1); #endregion return finalSize; } private List<double> heightlist = new List<double>(); public double GetItemHeight(int item) { if (item >= 0 && item < heightlist.Count) { return heightlist[item]; } else { return 0; } } }