博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF下制作的简单瀑布流效果
阅读量:5284 次
发布时间:2019-06-14

本文共 4580 字,大约阅读时间需要 15 分钟。

原文:

最近又在搞点小东西,美化界面的时候发现瀑布流效果比较不错.顺便就搬到了WPF,下面是界面

 

我对WEB前端不熟,JS和CSS怎么实现的,我没去研究过,这里就说下WPF的实现思路,相当简单.

1.最重要的就是每个子项的顺序填充,我是把界面看做N列,然后在每列里依次加载子项.最后结果就是,界面放一个Uniform,设置Columns,再添加几个ItemsControl.

2.添加Item的时候,判断每个ItemsControl的实际高度,把子项添加到最小的那个ItemsControl,这样避免了某一列拉得很长.

3.再做一层封装,就变成了一个支持Binding的WaterfallControl.

 

这里上几段控件的源码,供参考:

1.WaterfallControl.cs

1 [TemplatePart(Name = "grdRoot", Type = typeof(UniformGrid))]  2     public class WaterfallControl : ItemsControl  3     {  4         private UniformGrid grdRoot;  5   6         private List
itemsContorls; 7 8 public int Columns 9 { 10 get { return (int)GetValue(ColumnsProperty); } 11 set { SetValue(ColumnsProperty, value); } 12 } 13 14 // Using a DependencyProperty as the backing store for Columns. This enables animation, styling, binding, etc... 15 public static readonly DependencyProperty ColumnsProperty = 16 DependencyProperty.Register("Columns", typeof(int), typeof(WaterfallControl), new PropertyMetadata(3, OnColumnsChanged)); 17 18 private static void OnColumnsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 19 { 20 int columns = (int)e.NewValue; 21 if (columns < 1) 22 { 23 throw new ArgumentOutOfRangeException("Columns"); 24 } 25 var control = sender as WaterfallControl; 26 control.Columns = columns; 27 control.InitPanel(); 28 } 29 30 public WaterfallControl() 31 { 32 this.Loaded += WaterfallControl_Loaded; 33 this.itemsContorls = new List
(); 34 } 35 36 void WaterfallControl_Loaded(object sender, RoutedEventArgs e) 37 { 38 this.InitPanel(); 39 } 40 41 private void InitPanel() 42 { 43 if (!this.IsLoaded) 44 { 45 return; 46 } 47 48 grdRoot.Children.Clear(); 49 itemsContorls.Clear(); 50 for (var i = 0; i < this.Columns; i++) 51 { 52 var ic = new ItemsControl(); 53 ic.ItemTemplate = this.ItemTemplate; 54 ic.VerticalAlignment = System.Windows.VerticalAlignment.Top; 55 grdRoot.Children.Add(ic); 56 itemsContorls.Add(ic); 57 } 58 59 if (this.ItemsSource != null) 60 { 61 var enumerator = this.ItemsSource.GetEnumerator(); 62 while (enumerator.MoveNext()) 63 { 64 this.AddChild(enumerator.Current); 65 } 66 } 67 } 68 69 public override void OnApplyTemplate() 70 { 71 base.OnApplyTemplate(); 72 grdRoot = (UniformGrid)this.GetTemplateChild("grdRoot"); 73 } 74 75 protected override void AddChild(object value) 76 { 77 var ic = itemsContorls.OrderBy(t => t.ActualHeight).FirstOrDefault(); 78 ic.Items.Add(value); 79 ic.UpdateLayout(); 80 } 81 82 protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 83 { 84 if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Remove) 85 { 86 var enumerator = e.NewItems.GetEnumerator(); 87 while (enumerator.MoveNext()) 88 { 89 if (e.Action == NotifyCollectionChangedAction.Add) 90 { 91 this.AddChild(enumerator.Current); 92 } 93 else 94 { 95 foreach (var ic in this.itemsContorls) 96 { 97 ic.Items.Remove(enumerator.Current); 98 } 99 }100 }101 }102 }103 }
View Code

2.WaterfallControl的样式

View Code

3.调用

WaterfallControl继承自ItemsControl,所以和ItemsControl的使用没有区别,只需要额外指定一个Columns即可.

 

可能遇到的问题:

1.遇到图片不能直接计算高度,可能导致某列很长.可以用扩展属性给图片指定一个初始占位高度.

2.遇到界面大小变化,列数是不是应该动态变化,这个要实现也简单,监视下Window.SizeChanged,然后改变Columns就行了.

3.我直接把ScrollViewer放到WaterfallControl的模板里了,建议抽出来,监视下滚动事件,实现滚动到底加载数据.

4.不知道是否有更简单明了的方法.

posted on
2019-04-01 23:40 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/10640039.html

你可能感兴趣的文章
js高阶函数应用—函数防抖和节流
查看>>
eclipse 中java/scala 混合的maven项目 工作环境篇
查看>>
顺序栈与两栈共享空间-C语言实现
查看>>
【mongo】可以用localhost启动,无法用ip启动问题的解决
查看>>
【QT】视频播放
查看>>
揭开Redis的神秘面纱
查看>>
Object流
查看>>
转 10 个 Nginx 的安全提示
查看>>
Windows Phone开发(8):关于导航的小技巧 转:http://blog.csdn.net/tcjiaan/article/details/7285062...
查看>>
字符串类型 字符串下标 字符串的方法 切片 for循环的一些总结
查看>>
Ajax学习笔记1之第一个Ajax应用程序
查看>>
css3新单位vw、vh、vmin、vmax的使用详解(转载)
查看>>
软件测试培训第30天
查看>>
创建守护进程步骤与setsid()
查看>>
[iOS]Win8下iTunes无法连接iPhone版本的解决方法
查看>>
鸟哥私房菜基础篇:Linux 磁碟与档案系统管理习题
查看>>
垂直居中及水平垂直居中方案(共15种)
查看>>
JavaScript高级程序设计26.pdf
查看>>
jquery 对 table 的操作
查看>>
centos7 关闭防火墙
查看>>