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

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

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

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

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

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

1.WaterfallControl.cs

 [TemplatePart(Name = "grdRoot", Type = typeof(UniformGrid))]
public class WaterfallControl : ItemsControl
{
private UniformGrid grdRoot; private List<ItemsControl> itemsContorls; public int Columns
{
get { return (int)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
} // Using a DependencyProperty as the backing store for Columns. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ColumnsProperty =
DependencyProperty.Register("Columns", typeof(int), typeof(WaterfallControl), new PropertyMetadata(, OnColumnsChanged)); private static void OnColumnsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
int columns = (int)e.NewValue;
if (columns < )
{
throw new ArgumentOutOfRangeException("Columns");
}
var control = sender as WaterfallControl;
control.Columns = columns;
control.InitPanel();
} public WaterfallControl()
{
this.Loaded += WaterfallControl_Loaded;
this.itemsContorls = new List<ItemsControl>();
} void WaterfallControl_Loaded(object sender, RoutedEventArgs e)
{
this.InitPanel();
} private void InitPanel()
{
if (!this.IsLoaded)
{
return;
} grdRoot.Children.Clear();
itemsContorls.Clear();
for (var i = ; i < this.Columns; i++)
{
var ic = new ItemsControl();
ic.ItemTemplate = this.ItemTemplate;
ic.VerticalAlignment = System.Windows.VerticalAlignment.Top;
grdRoot.Children.Add(ic);
itemsContorls.Add(ic);
} if (this.ItemsSource != null)
{
var enumerator = this.ItemsSource.GetEnumerator();
while (enumerator.MoveNext())
{
this.AddChild(enumerator.Current);
}
}
} public override void OnApplyTemplate()
{
base.OnApplyTemplate();
grdRoot = (UniformGrid)this.GetTemplateChild("grdRoot");
} protected override void AddChild(object value)
{
var ic = itemsContorls.OrderBy(t => t.ActualHeight).FirstOrDefault();
ic.Items.Add(value);
ic.UpdateLayout();
} protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Remove)
{
var enumerator = e.NewItems.GetEnumerator();
while (enumerator.MoveNext())
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
this.AddChild(enumerator.Current);
}
else
{
foreach (var ic in this.itemsContorls)
{
ic.Items.Remove(enumerator.Current);
}
}
}
}
}
}

2.WaterfallControl的样式

<Style TargetType="controls:WaterfallControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:WaterfallControl">
<ScrollViewer HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
<UniformGrid Name="grdRoot" Columns="{TemplateBinding Columns}"> </UniformGrid>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

3.调用

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

可能遇到的问题:

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

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

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

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

WPF下制作的简单瀑布流效果的更多相关文章

  1. thinphp下拉获取更多瀑布流效果

    html页面 <body> <script type="text/javascript" src="jquery.min.js">< ...

  2. wpf 客户端【JDAgent桌面助手】开发详解(三) 瀑布流效果实现与UI虚拟化优化大数据显示

    目录区域: 业余开发的wpf 客户端终于完工了..晒晒截图 wpf 客户端[JDAgent桌面助手]开发详解-开篇 wpf 客户端[JDAgent桌面助手]详解(一)主窗口 圆形菜单... wpf 客 ...

  3. 利用JS实现简单的瀑布流效果

    哈哈, 我又来啦, 在这一段时间里, 我简单的学习了一下javascript(JS), 虽然不是很懂啦, 但是我也简单的尝试着做了点小东西, 就比如现在流行的瀑布流效果, 经过我的努力终于成功的完成了 ...

  4. 实现RecyclerView下拉刷新和上拉加载更多以及RecyclerView线性、网格、瀑布流效果演示

    实现RecyclerView下拉刷新和上拉加载更多以及RecyclerView线性.网格.瀑布流效果演示 效果预览 实例APP 小米应用商店 使用方法 build.gradle文件 dependenc ...

  5. RecyclerView实现瀑布流效果(图文详解+源码奉送)

    最近有时间研究了一下RecyclerView,果然功能强大啊,能实现的效果还是比较多的,那么今天给大家介绍一个用RecyclerView实现的瀑布流效果. 先来一张效果图: 看看怎么实现吧: 整体工程 ...

  6. 手把手教你js原生瀑布流效果实现

    手把手教你js原生瀑布流效果实现 什么是瀑布流效果 首先,让我们先看一段动画: 在动画中,我们不难发现,这个动画有以下特点: 1.所有的图片的宽度都是一样的 2.所有的图片的高度是不一样的 3.图片一 ...

  7. Android UI 之WaterFall瀑布流效果

        所谓瀑布流效果,简单说就是宽度相同但是高度不同的一大堆图片,分成几列,然后像水流一样向下排列,并随着用户的上下滑动自动加载更多的图片内容.     语言描述比较抽象,具体效果看下面的截图:   ...

  8. js图片瀑布流效果

    要实现图片瀑布流效果,首先得准备几张图片. html的部分比较简单就是将图片加载到浏览器就可以了 代码如下(注意放的图片多一点要不然之后无法滑动鼠标就无法达到瀑布流效果): <!DOCTYPE ...

  9. 使用JS实现图片展示瀑布流效果

    不知大家有没有发现,一般的图片展示网站都会使用瀑布流效果,所谓的瀑布流 就是网站内的图片不会一下子全缓存出来,而是等你滚动到一定的距离的时候, 下面的图片才会继续缓存,并且图片也是随机出现的,只是宽度 ...

随机推荐

  1. 如何分析解读systemstat dump产生的trc文件

    ORACLE数据库的systemstat dump生成trace文件虽然比较简单,但是怎么从trace文件中浩如烟海的信息中提炼有用信息,并作出分析诊断是一件技术活,下面收集.整理如何分析解读syst ...

  2. 【Linux】将Oracle安装目录从根目录下迁移到逻辑卷

    [Linux]将Oracle安装目录从根目录下迁移到逻辑卷 1.1  BLOG文档结构图 1.2  前言部分 1.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到 ...

  3. RabbitMQ入门教程——安装及配置

    RabbitMQ是一个消息代理,一个消息系统的媒介,提供了一个通用的消息发送及接收平台,并且能够保障消息传输过程中的安全.使用erlang语言开发,开源,在易用性.扩展性.高可用性等方面表现不俗 技术 ...

  4. 安装Mysql 5.7.1

    现在安装MySQL变成了一件非常人性化的事情,因为有了MySQL-installer这个工具,它可以帮助我们全程安装MySQL.     下面我来简单介绍一下如何使用,以供新手学习:     .首先下 ...

  5. iOS拍照上传后,在web端显示旋转 Swift+OC版解决方案

    问题描述: 手机头像上传,遇到一个怪现象,就是拍照上传时,手机端显示头像正常,但在web端查看会有一个左旋90度的问题. 并且照片竖怕才会有此问题,横拍不存在. 原因分析: 手机拍照时,用相机拍摄出来 ...

  6. PDO链接mysql学习笔记

    <?php //PDO链接mysql//dsn三种写法: //dsn01 $dsn = 'mysql:host=localhost;dbname=mysql'; //$dsn = 'mysql: ...

  7. scala 第一课

    val msg="Hello,World" Scala 可以根据赋值的内容推算出变量的类型.这在Scala语言中成为"type inference". Scal ...

  8. chrome内核浏览器input边框

    直接给input加outline:none和设置input {outline:none}都没效 最后逼得没法,*:focus { outline: none; },然后整个世界就安静了,嚯嚯

  9. C++浅析——虚表和虚表Hook

    为了探究虚表的今生前世,先来一段测试代码 虚函数类: class CTest { public: int m_nData; virtual void PrintData() { printf(&quo ...

  10. 荒芜的周六-PHP之面向对象(三)

    hi 又是开森的周六了.积攒的两周的衣服,终于是差不多洗完了.大下午的才来学点东西~~ 1.PHP面向对象(三) 四.OOP的高级实践 4.3 Static-静态成员 <?phpdate_def ...