原文: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. 关于用strace工具定位vrrpd进程有时会挂死的bug

    只做工作总结备忘之用. 正在烧镜像,稍总结一下进来改bug遇到的问题. 一个项目里要用到L3 switch的nat,vrrp功能,但实地测试中偶然出现write file挂死的情况,但不是必现.交付在 ...

  2. 【55.70%】【codeforces 557A】Ilya and Diplomas

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  3. 【2186】Popular Cows(强连通分支及其缩点)

    id=2186">[2186]Popular Cows(强联通分支及其缩点) Popular Cows Time Limit: 2000MS   Memory Limit: 65536 ...

  4. ios开发多线程二:NSOperationQueue的基本使用

    #import "ViewController.h" #import "XMGOperation.h" @interface ViewController () ...

  5. CentOS下安装和配置MySQL-JDK-Tomcat-Nginx(个人官网环境搭建手册)

    今天,重新弄我的个人云主机的环境,准备运营自己用Java写的个人官网等网站. 服务器环境:阿里云CentOS 6.4位 包括以下脚本在内的绝大部分命令和脚本,都是我亲自执行过,靠谱的. 完整的&quo ...

  6. Android UI:看看Google官方自定义带旋转动画的ImageView-----RotateImageView怎么写(附 图片淡入淡...)

    众所周知,想要让ImageView旋转的话,可以用setRotation()让其围绕中心点旋转,但这个旋转是不带动画的,也就是旋转屏幕时图片噌的一下就转过去了,看不到旋转的过程,此UI体验不大好,为此 ...

  7. Android JNI编程(三)——C语言指针的初步认识、指针变量、互换两个数、函数返回多个值

    版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一.什么是指针? 简单来说: 指针就是内存地址      内存地址就是指针. ...

  8. 【33.33%】【codeforces 552B】Vanya and Books

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  9. SqlBulkCopy 帮助类

    using System;using System.Collections.Generic;using System.Configuration;using System.Data;using Sys ...

  10. Java中sleep()与wait()区别

    学习时正好碰到这两个方法,就查阅相关资料,并通过程序实现,进行区别一下: 1.每个对象都有一个锁来控制同步访问,Synchronized关键字可以和对象的锁交互,来实现同步方法或同步块.sleep() ...