原文:WPF中的 Layout To Layout

  WPF中的 Layout To Layout

                            周银辉

WPF的布局功能异常强大,当有时我们会有一些奇怪的需求:布局之间的切换。比如动态地将控件在UniformGrid布局和StackPanel布局之间切换。这种需求是有意义的,比如Blend中的DesignWorkspace和AnimationWorkspace切换功能。WPF可以轻松做到这一点。

1, 无过渡动画的直接切换:

这没有什么讨论的必要了,要将控件从源布局切换到目标布局,只需要简单地将该控件从源布局控件中删除然后添加到目标布局控件中就可以了。

2, 有过度动画的切换:

这才是我们这篇文章要讨论的。为了明白我在说什么,你可以先下载这个程序运行一下以观察该类型的切换。

基本原理

假设有几个Button控件要在UniformGrid布局和StackPanel布局之间切换,我们可以这样来实现:

就其中的一个按钮btn1而言,无论btn1被加载到哪个面板中,都是先从上一个面板中将btn1删除,然后在调用另外一个面板的Children.Add方法,该动作都是瞬间完成的,除非修改面板内部逻辑,不可以产生动画,更不可能有过度效果.

那么事实上,我们既不将btn1放到UnifromGrid中也不把它放到StackPanel中,而是将它放到一个Canvas中.并且Canvas与UnifromGrid以及StackPanel重合. 而放到UnifromGrid或StackPanel中的是另外一个元素:我们称为LayoutToLayoutTarget(Target),切换布局的时候,事实上,我们是将Target从一个面板中删除然后在加到另一个面板中,与此同时,我们的btn1参照Target在新面板中的位置和大小来作为其动画的目标值,然后利用动画来到变化到此值.当由于其他原因(比如用户改变窗口大小等)导致Target位置或大小发生变化时,我们的btn1也会立即做出相应的变化(而不采用动画来渐变了).可以看出btn1始终在Canvas中,只是大小和位置发生了变化,而让人产生了错觉

这里的btn1只是一个特例,为了让所有的控件都可以达到这个效果而不仅仅是Button,我们就使用LayoutToLayoutHost来包含其他控件(host.Child=myBtn).Host的行为为上面的btn1完全一样.

public class LayoutToLayoutTarget : Border

LayoutToLayoutTarget用来指示LayoutToLayoutHost的大小以及将放置在什么位置.当布局变化时,先将LayoutToLayoutTarget变化到合适的位置和大小, 然后LayoutToLayoutHost再根据LayoutToLayoutTarget的大小和位置来进行动画

public class LayoutToLayoutHost : Border

LayoutToLayoutHost用来Host控件. LayoutToLayoutTarget用来指示LayoutToLayoutHost的大小以及将放置在什么位置.当布局变化时,先将LayoutToLayoutTarget变化到合适的位置和大小, 然后LayoutToLayoutHost再根据LayoutToLayoutTarget的大小和位置来进行动画

使用前的准备工作是:

//初始化一个LayoutToLayoutTarget

LayoutToLayoutTarget target = new LayoutToLayoutTarget();

//设置目标大小

target.MinWidth = 80;

target.MinHeight = 50;

this.targets.Add(target);

//将其放置在源布局控件中

this.uniformGrid1.Children.Add(target);

//初始化一个LayoutToLayoutTarget

LayoutToLayoutHost host = new LayoutToLayoutHost();

//先将host放在Canvas中

this.canvas1.Children.Add(host);

//demoButton为我们要改变布局的控件

Button demoButton = new Button();

demoButton.Content = "# " + i;

//将它放在host中

host.Child = demoButton;

//将host和target联系起来

host.BindToTarget(target);

改变布局时:

//将target从源布局控件中删除

this.uniformGrid1.Children.Remove(target)

//将target添加到目标布局控件中

this.stackPanel1.Children.Add(target);

//开始动画

host.BeginAnimating(false);

如果觉得一头雾水的话,可以在这里下载DEMO谢谢

WPF中的 Layout To Layout的更多相关文章

  1. WPF笔记(2.4 Grid)——Layout

    原文:WPF笔记(2.4 Grid)--Layout 第一章已经简单介绍过这个容器,这一节详细介绍.Grid一般是用表格(Grid.Row 和Grid.Column )的,比StackPanel更细致 ...

  2. WPF笔记(2.2 DockPanel)——Layout

    原文:WPF笔记(2.2 DockPanel)--Layout 读完了这一节,发现DockPanel就是过去winform中的Dock属性.原来的Dock属性是子控件设置,而其父亲级别不用设置.现在W ...

  3. WPF笔记(2.5 Canvas)——Layout

    原文:WPF笔记(2.5 Canvas)--Layout Canvas是最精确的布局容器--绝对定位,此书作者不建议使用,以为控件的大小一般会随着内部字体图片的动态生成而自动变化,所以使用前三种布局是 ...

  4. WPF笔记(2.6 ViewBox)——Layout

    原文:WPF笔记(2.6 ViewBox)--Layout 在Canvas外面包一层ViewBox,可以使Canvas内的控件填充整个ViewBox,并随着ViewBox的大小变化而同步变化,这是因为 ...

  5. WPF笔记(2.3 StackPanel)——Layout

    原文:WPF笔记(2.3 StackPanel)--Layout StackPanel用于小规模的排版布局,比如说一个局部下几个textbox和Button啦.Orientation属性有Vertic ...

  6. flutter系列之:flutter中常用的container layout详解

    目录 简介 Container的使用 旋转Container Container中的BoxConstraints 总结 简介 在上一篇文章中,我们列举了flutter中的所有layout类,并且详细介 ...

  7. WPF中log4net的用法

    WPF中如何使用log4nethttp://www.cnblogs.com/C-Sharp2/archive/2013/04/12/WPF-LOG4NET.html Apache log4net Ma ...

  8. 在WPF中自定义你的绘制(二)

    原文:在WPF中自定义你的绘制(二)   在WPF中自定义你的绘制(二)                                                                 ...

  9. wpf中的样式与模板

    1.WPF样式类似于Web应用程序中的CSS,在WPF中可以为控件定义统一的样式(Style).样式属于资源的一种,例如为Button定义统一的背景颜色和字体: <Window.Resource ...

随机推荐

  1. stm32的DMA重新工作

    下面是在战舰V3寄存器程序例子中找到的: //开启一次DMA传输void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx){    DMA_CHx->CCR&a ...

  2. linux系统下安装与配置apache

    搭建环境:VMware上虚拟的linux 主机:win  7 安装linux下的Apache前准备: 1.httpd服务的配置文件,默认存储路径:/etc/httpd/conf/httpd.conf( ...

  3. 远离“精神乞丐”(IBM的前CEO郭士纳把员工分为四种类型)

    语音丨吴伯凡 乞丐与其说是一种身份, 不如说是一种精神状态, 习惯性索取且心安理得, 习惯性寻求安慰,习惯性抱怨, 与之截然对立的, 是“操之在我”(Proactive)的精神, 乞丐型员工是公司内部 ...

  4. tomcat 启动项目时出现 ZipException: error in opening zip file

    错误情况 项目用 maven 打好 war 包后放到 tomcat 下,启动 tomcat,出现以下错误 3-Nov-2017 12:21:44.346 严重 [localhost-startStop ...

  5. 前端开发必备调试工具(Chrome的F12自带的功能和firebug插件差不多)

    前端开发必备调试工具(Chrome的F12自带的功能和firebug插件差不多) 一.总结 Chrome的F12自带的功能和firebug插件差不多 二.前端开发必备调试工具 在前端开发中我们经常会要 ...

  6. [React Router v4] Render Multiple Components for the Same Route

    React Router v4 allows us to render Routes as components wherever we like in our components. This ca ...

  7. 常用JS验证函数总结

    JS验证Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/- ...

  8. Identifying a distributed denial of service (DDOS) attack within a network and defending against such an attack

    The invention provides methods, apparatus and systems for detecting distributed denial of service (D ...

  9. BFKit:对常用 UIButton,UIColor,UIDevice,UIFont ,UIImage 等开发类进行了扩展

    BFKit对常用于开发的类进行了扩展,整合了多个常用的控件和开发所需要的功能,是一个通用性的类库.集成后可以帮助更快的App开发.有兴趣的同学可以看看哦. http://code4app.com/io ...

  10. 【BZOJ 1031】[JSOI2007]字符加密Cipher(后缀数组模板)

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1031 [题意] [题解] 后缀数组模板题; 把整个字符串扩大一倍. 即长度乘2 然后搞 ...