我们在使用像ListBox的列表控件时,我们都知道可以通过其ItemsPanel的依赖项属性来自定义一个面板来放置列表控件中的列表项。除了CLR库提供的几个面板外,我们完全可以把自己写的面板作为项列表的容器。

先给各位看看效果。

如何?效果还好吧?

面板的原理是这样的:

1、从Panel类派出一个类,我命名为MyPanel。

2、重写MeasureOverride方法,分别计算所有子元素的大小。

3、重写ArrangeOverride方法,为每个子元素随机生成X和Y坐标,然后再用这个随机生的坐标来放置子元素。

4、为了能隔一段时间自动排版一次,我就加入了一个DispatcherTimer,并公开一个SwapInterval属性,可以为调用者设置计时器的执行音隔,以秒为单位。

5、后来想想,如果每次都仅仅调用InvalidateArrange方法来重新排列子元素,好像有些枯燥,不如在重新排列之间弄一些动画效果好看点。于是,我就在重新排列子元素之前让面板“淡出”;当面板排列子元素完成后,再来个“淡入”效果,不错。只是对Opacity属性进行动画处理就可以了,也不费事。

好,整体的思路就是这样,然后把这个面板用到ListBox等列表控件的ItemsPanel上就行。

            <ListBox.ItemsPanel>
<ItemsPanelTemplate>
<local:MyPanel SwapInterval="6"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>

下面我贴一下整个MyPanel类的代码,以供大家参考。(代码进行了修订)

    public class MyPanel:Panel
{
Random rand = null;
DispatcherTimer Timer = null; public MyPanel()
{
rand = new Random();
Timer = new DispatcherTimer();
Timer.Interval = TimeSpan.FromSeconds(SwapInterval);
Timer.Tick += Timer_Tick;
Timer.Start();
} #region 属性
public static readonly DependencyProperty SwapIntervalProperty = DependencyProperty.Register("SwapInterval", typeof(double), typeof(MyPanel), new PropertyMetadata(10d, new PropertyChangedCallback(SwapIntervalChanged), new CoerceValueCallback(CoerceValCallback))); private static void SwapIntervalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MyPanel p = d as MyPanel;
double sec = (double)e.NewValue;
p.Timer.Stop();
p.Timer.Interval = TimeSpan.FromSeconds(sec);
p.Timer.Start();
} private static object CoerceValCallback(DependencyObject d, object baseValue)
{
// 通过该方法测检依赖项属性的值
// 如果设置的值小于5秒,就自动改为5秒
double dv = (double)baseValue;
if (dv < 5d)
{
dv = 5d;
}
return dv;
} /// <summary>
/// 切换动画间隔,以秒为单位
/// </summary>
public double SwapInterval
{
get { return (double)GetValue(SwapIntervalProperty); }
set { SetValue(SwapIntervalProperty, value); }
}
#endregion void Timer_Tick(object sender, EventArgs e)
{
DoubleAnimation dat = new DoubleAnimation();
dat.From = 1d;
dat.To = 0d;
dat.Duration = TimeSpan.FromMilliseconds();
dat.Completed += (sd, arg) =>
{
// 当动画完成时,面板的Opacity为0
// 此时重新排列子元素
this.InvalidateArrange();
DoubleAnimation datBack = new DoubleAnimation();
datBack.From = 0d;
datBack.To = 1d;
datBack.Duration = TimeSpan.FromSeconds();
// 子元素排列完成后,再执行一个动画
// 将Opacity再改为1
this.BeginAnimation(OpacityProperty, datBack);
};
// 开始动画,隐藏面板
this.BeginAnimation(OpacityProperty, dat);
} protected override Size MeasureOverride(Size availableSize)
{
// 处理子元素的大小
foreach (UIElement u in InternalChildren)
{
// 一定要对每个子元素调用Measure
// 不然,就看不到子元素了
u.Measure(availableSize);
}
// 如果不要求精确计算子元素占了多少
// 空间,可以直接返回0-0的Size,但不
// 要返回正无穷大,否则后果自负
return new Size();
} protected override Size ArrangeOverride(Size finalSize)
{
// 通过该方法对子元素进行排列
foreach (UIElement item in InternalChildren)
{
// 算出子元素的坐标的随机值
double maxX = finalSize.Width - item.DesiredSize.Width;
double maxY = finalSize.Height - item.DesiredSize.Height;
if (maxX <=0d)
{
maxX = 1d;
}
if (maxY <= 0d)
{
maxY = 1d;
}
double X = rand.Next(, (int)maxX);
double Y = rand.Next(, (int)maxY);
// 调用Arrange方法安排子元素放在哪个位置
item.Arrange(new Rect(X, Y, item.DesiredSize.Width, item.DesiredSize.Height));
}
return finalSize;
}
}

代码可以移植到Windows Phone或Windows StoreApp中,原理都是一样的。

其他代码就没有必要贴了,免得影响大家看帅哥美女,我把整个项目上传就是了。

下载地址:http://files.cnblogs.com/tcjiaan/MyLayoutPanel.zip

【WPF】制作自定义的列表项面板的更多相关文章

  1. WPF中反转3D列表项

    原文:WPF中反转3D列表项 WPF中反转3D列表项                                                         周银辉记得在苹果电脑中有一个很酷的 ...

  2. 每日学习心得:SharePoint 2013 自定义列表项添加Callout菜单项、文档关注、SharePoint服务端对象模型查询

    前言: 前一段时间一直都比较忙,没有什么时间进行总结,刚好节前项目上线,同时趁着放假可以好好的对之前遇到的一些问题进行总结.主要内容有使用SharePoint服务端对象模型进行查询.为SharePoi ...

  3. WPF界面设计技巧(4)—自定义列表项样式

    原文:WPF界面设计技巧(4)-自定义列表项样式 有前面修改按钮样式的基础,我们可以尝试来定制一个即好看又好用的 ListBox ,今天先来讲“好看”部分. 打开 Microsoft Visual S ...

  4. WPF界面设计技巧(5)—自定义列表项呈现内容

    原文:WPF界面设计技巧(5)-自定义列表项呈现内容 接续上次的程序,稍微改动一下原有样式,并添加一个数据模板,我们就可以达成下面这样的显示功能: 鼠标悬停于文件列表项上,会在工具提示中显示图像缩略图 ...

  5. SharePoint 2013 自定义翻页显示列表项

    项目需求:自定义开发一个能分页显示列表项的小部件,允许左右翻页,能根据用户权限来显示管理链接等. 效果如下: 技术要求:使用sharepoint rest API 来获取列表项,这样性能高,能够快速响 ...

  6. 自定义ListView适配器Adapter引用布局文件的情况下实现点击列表项时背景颜色为灰色

    listview控件设置适配器的时候,如果使用自定义的adapter,比如MyArrayAdapter extends ArrayAdapter<String> 如果listitem布局文 ...

  7. 【百度地图API】如何制作自定义样式的公交导航结果面板?

    原文:[百度地图API]如何制作自定义样式的公交导航结果面板? 摘要: 百度地图API有默认的公交导航结果面板,但样式比较单一:而百度地图上的结果面板就比较美观.如何利用百度地图API来制作一个比较美 ...

  8. SharePoint 列表项通过自定义WebService读取

    简述:给其他系统提供集成,发现SharePoint自带的WebService各种不好使,索性就自己写一点,也当做自己学习的记录了.当然内容比较简单,希望大侠们不要介意,也不要骂我啊.好了,进入正题吧. ...

  9. (2017.9.27) 自定义列表项 list-style 使用心得

    今天给某公司做招聘专页.早上完成设计图,下午开始排版.页面套用了我之前做的某人才局的招聘页面,导航栏.banner 很快就出来了.这次内容里我有些地方用了列表,当然要用 <ul> < ...

随机推荐

  1. 解决hadoop启动后datanode无法启动问题

    hadoop部署完成后datanode无法启动问题解决 1.检查是否有遗留的hadoop进程还在运行,如果有的话,先stop-all.sh或kill杀掉: 2.在master节点上,删除/tmp/ha ...

  2. C# interface

    我们学习了interface,即接口,其与抽象类有点像,但是他们也有一些区别,比如类不能多重继承但是接口却可以多重继承. 接口只包含方法.委托或事件和属性的签名(接口包含的成员).不能包含字段(因为字 ...

  3. Python成长笔记 - 基础篇 (十)

    本节内容 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queu ...

  4. Linq to Sql 聚合查询

    //输出体重最大的同学,并要求最大体重得大于39,并按照体重大下,对分组结果进行排序. var result = from query in linq.Student group query by q ...

  5. [java基础]文档注释

    转载自:http://blog.163.com/hui_san/blog/static/5710286720104191100389/ 前言 Java 的语法与 C++ 及为相似,那么,你知道 Jav ...

  6. 在mac下svn冲突或其它什么原因无法更新svn副本或是必须要删除svn信息时,如何清除svn信息

    find . -type d -name ".svn"|xargs rm -rf 出处: http://blog.csdn.net/springsky_/article/detai ...

  7. HTML5-属性

    点击图片打开详细介绍页面

  8. Mac OS X上编写 ASP.NET vNext 系列中断和再开声明

    这个系列其实已经中断有一段时间了,主要是由两个原因: 第一是微软那边把以前的KRE改成了XRE,所以导致前两篇有点过时了. 第二是自己年前1月份被裁员,Mac的机器被回收,再加上忙于和公司扯皮和找工作 ...

  9. node(redis)

    给出node下redis操作的简单例子: var redis = require("redis"), client = redis.createClient(6379,'127.0 ...

  10. Expression Tree 扩展MVC中的 HtmlHelper 和 UrlHelper

    表达式树是LINQ To everything 的基础,同时各种类库的Fluent API也 大量使用了Expression Tree.还记得我在不懂expression tree时,各种眼花缭乱的A ...