原文: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. Xavier Initialization 的理解与推导(及实现)

    在 caffe mnist tutorial 的实现中,有如下的语句: weight_filter = {type: "xavier"}; 随后的解释中指出,本实现将使用 xavi ...

  2. ios开发网络学习四:NSURLConnection大文件断点下载

    #import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDelegate> ...

  3. zookeeper无法启动&quot;Unable to load database on disk&quot;

    自己的虚拟机集群.一次强制关机后,发现slave2的zookeeper起不来了 http://blog.csdn.net/ashic/article/details/47088299 下午5点29:5 ...

  4. js进阶正则表达式14验证邮编(input的pattern属性)(正则表达式加起^始$)

    js进阶正则表达式14验证邮编(input的pattern属性)(正则表达式加起^始$) 一.总结 1.input的pattern属性:里面可以直接放正则表达式,<input type=&quo ...

  5. OpenCV编译步骤

    作者:朱金灿 来源:http://blog.csdn.net/clever101 1. 从网上下载OpenCV安装包,然后安装. 2. 打开CMake 2.8设置源码路径和生成的VS工程文件路径.(首 ...

  6. [Git] Use git add --patch for better commit history and mitigating bugs

    Let's split our changes into separate commits. We'll be able to check over our changes before stagin ...

  7. NOIP 模拟 序列操作 - 无旋treap

    题意: 一开始有n个非负整数h[i],接下来会进行m次操作,第i次会给出一个数c[i],要求选出c[i]个大于0的数并将它们-1,问最多可以进行多少次? 分析: 首先一个显然的贪心就是每次都将最大的c ...

  8. Framework for Graphics Animation and Compositing Operations

    FIELD OF THE DISCLOSURE The subject matter of the present disclosure relates to a framework for hand ...

  9. matlab 运行 AlexNet

    0. alexnet 工具箱下载 下载地址:Neural Network Toolbox(TM) Model for AlexNet Network 需要先注册(十分简单),登陆,下载: 下载完成之后 ...

  10. Java访问修饰符(转)

    类.方法.成员变量和局部变量的可用修饰符 修饰符 类 成员方法 构造方法 成员变量 局部变量 abstract(抽象的) √ √ - - - static (静态的) - √ - √ - public ...