曾经总认为动态布局是个非常麻烦的问题。是个非常须要功力的问题。可是貌似在.NET中,在WPF中却不是那么的麻烦。以下介绍我如今实现的一个动态布局的实例。

由于有需求,所以困难得克服!而我们的需求表名。不同的用户须要的界面元素是不一样的,我们总不能每次都去改动代码吧!所以,须要完毕动态布局。

这里主要完毕这样一个功能:

1、动态画线

2、动态new控件

3、线和控件都是可拖拽并任意放置位置的

4、线和控件是可删除的

5、控件是可绑定属性和事件的

要完毕这种功能,我们首先得定义三个鼠标事件。即:左键down、move、up,右键删除(不能仅仅添加不删除啊)。

比如我要画一条线。那么左键down的时候,我就须要记录当前鼠标的位置。

左键down而且move的时候,要实时显示画出来的线。左键已经down而且左键up的时候记录位置而且完毕画线。

就是这样一个过程我们就完毕了动态画一条线。

动态生成控件就相对简单了。有了线,有了控件。连在一起,不就完毕布局了吗?当然是要把位置记录下来的。

代码上:

void Canvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//true表示当前是拖拽模式
if (currentPattern == "0")
{
//推断是否选的是主窗口
if (e.Source == mainCanvas)
{ }
else
{
_isDown = true;
_startPoint = e.GetPosition(mainCanvas);
_originalElement = e.Source as UIElement;
}
}
else if (currentPattern == "1")
{
_isDragging = true;
Canvas board = sender as Canvas;
_startPoint = e.GetPosition(board);
insertShape = CreateShape();
insertShape.Opacity = opacity / 2; Canvas.SetLeft(insertShape, e.GetPosition(board).X); //插入线条的起点x1/y1
Canvas.SetTop(insertShape, e.GetPosition(board).Y);
board.Children.Add(insertShape);
board.RegisterName(insertShape.Name, insertShape);
} } void Canvas_PreviewMouseMove(object sender, MouseEventArgs e)
{
//true表示当前是拖拽模式
if (currentPattern == "0")
{
if (_isDown)
{
//假设没有拖拽或者超出了界面
if ((_isDragging == false) && ((Math.Abs(e.GetPosition(mainCanvas).X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance) ||
(Math.Abs(e.GetPosition(mainCanvas).Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)))
{
_isDragging = true;
_originalLeft = Canvas.GetLeft(_originalElement); //获得原元素的位置
_originalTop = Canvas.GetTop(_originalElement);
_overlayElement = new Rectangle()
{
Width = _originalElement.RenderSize.Width,
Height = _originalElement.RenderSize.Height,
Fill = new VisualBrush(_originalElement),
Opacity = 0.8 //阴影的不透明性
};
Canvas.SetLeft(_overlayElement, _originalLeft);
Canvas.SetTop(_overlayElement, _originalTop);
mainCanvas.Children.Add(_overlayElement); }
//假设正在移动中,显示实时位置
if (_isDragging)
{
Point CurrentPosition = Mouse.GetPosition(mainCanvas);
//设置浮动对象的位置
Canvas.SetLeft(_overlayElement, _originalLeft + CurrentPosition.X - _startPoint.X);
Canvas.SetTop(_overlayElement, _originalTop + CurrentPosition.Y - _startPoint.Y);
}
}
}
else if (currentPattern == "1")
{
Canvas board = sender as Canvas;
if (_isDragging && insertShape != null)
{
if (insertShape is Line)
{
(insertShape as Line).X1 = 0; (insertShape as Line).X2 = e.GetPosition(board).X - _startPoint.X; //设置线条的X1/Y1/X2/Y2
(insertShape as Line).Y1 = 0; (insertShape as Line).Y2 = e.GetPosition(board).Y - _startPoint.Y;
}
}
} } void Canvas_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
//true表示当前是拖拽模式
if (currentPattern == "0")
{
if (_isDown)
{
if (_isDragging)
{
//将阴影位置设置为当前
Canvas.SetLeft(_originalElement, Canvas.GetLeft(_overlayElement));
Canvas.SetTop(_originalElement, Canvas.GetTop(_overlayElement));
Point _positionInOverlayElement = Mouse.GetPosition(_overlayElement);
mainCanvas.Children.Remove(_overlayElement);
_overlayElement = null;
}
//将移动标识设置为 false
_isDragging = false;
_isDown = false;
} }
else if (currentPattern == "1")
{ //假设是画线模式。则将拖拽设置为false。将透明度还原
_isDragging = false;
if (insertShape != null)
insertShape.Opacity = opacity;
}
}

有了这三个基本的事件。你就能够非常轻松的完毕动态布局了。怎样保存的呢?我是把各个控件的位置放在了数据库中。载入的时候将位置信息读出来。

		private void btnSave_Click(object sender, RoutedEventArgs e)
{
//遍历全部的界面控件,拿到他们的位置信息,保存。
List<A> listAConfig = new List<A>();
//获得界面上全部的Line元素
List<Line> listLine = GetElementFormUI.GetChildObjects<Line>(mainCanvas);
for (int i = 0; i < listLine.Count; i++) {
Line l = listLine[i] ;
A enAConfig = new A();
enAConfig .S_ID = DateTime.Now.ToFileTime().ToString();
enAConfig .S_NAME = l.Name;
enAConfig .S_SHAPETYPE = "Line";
enAConfig .I_LEFT =decimal.Parse(Canvas.GetLeft(l as UIElement).ToString());
enAConfig .I_TOP = decimal.Parse(Canvas.GetTop(l as UIElement).ToString());
enAConfig .I_X2 = decimal.Parse(l.X2.ToString());
enAConfig .I_Y2 = decimal.Parse(l.Y2.ToString());
listAConfig.Add(enAConfig );
}
//推断是否保存成功
if (ServiceFactory.GetAConifgService().AddAConfig(listAConfig))
{
MessageBox.Show("保存成功。", "恭喜!", MessageBoxButton.OK);
}
else {
MessageBox.Show("保存失败! ", "警告! ", MessageBoxButton.OK);
} }

至此,我们完毕了动态布局的设定和保存,尝试一下吧!

WPF实现界面动态布局的更多相关文章

  1. WPF案例 (六) 动态切换UI布局

    原文:WPF案例 (六) 动态切换UI布局 这个Wpf示例对同一个界面支持以ListView或者CardView的布局方式呈现界面,使用控件ItemsControl绑定数据源,使用DataTempla ...

  2. 【源码分享】WPF漂亮界面框架实现原理分析及源码分享

    1 源码下载 2 OSGi.NET插件应用架构概述 3 漂亮界面框架原理概述 4 漂亮界面框架实现  4.1 主程序  4.2 主程序与插件的通讯   4.2.1 主程序获取插件注册的服务   4.2 ...

  3. WPF中的常用布局 栈的实现 一个关于素数的神奇性质 C# defualt关键字默认值用法 接口通俗理解 C# Json序列化和反序列化 ASP.NET CORE系列【五】webapi整理以及RESTful风格化

    WPF中的常用布局   一 写在开头1.1 写在开头微软是一家伟大的公司.评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好,应该抛弃对微软和微软的技术的偏见. 1.2 本文内容本文主要内容 ...

  4. 【腾讯Bugly干货分享】Android动态布局入门及NinePatchChunk解密

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57c7ff5d53bbcffd68c64411 作者:黄进——QQ音乐团队 摆脱 ...

  5. 界面动态加载时报NullPointException

    今天在做环境监测的模拟软件时,登陆页面报NullPointException 一般像我们初始化Button时,是Button btn=(Button)findViewById(R.id.button1 ...

  6. WPF中的常用布局

    一 写在开头1.1 写在开头评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好. 1.2 本文内容本文主要内容为WPF中的常用布局,大部分内容转载至https://blog.csdn.net ...

  7. android开发学习笔记系列(4)--android动态布局

    前言 在做一个有关苏果APP的项目中,但是fuck的是,我完全使用相对布局之后及线性布局之后发现坑爹的事情了,屏幕不能适配,这是多大的痛,意味着,必须使用相应的代码实现动态布局!呵呵,不做项目不知道, ...

  8. [How to] 动态布局可变高度的cell的应用

    1.简介 代码:https://github.com/xufeng79x/DynamicChangeableCell 微博界面,微信和QQ聊天界面,这些界面的布局大都不确定,且每一条消息的高度也不一样 ...

  9. 3.Dynamic Layout 动态布局。在槽中处理布局

    在应用程序中,一个界面的布局基本都是固定的. 在这个实例中,我们把管理布局的代码放在槽中.这样点击一次按钮,触发槽.布局改变一次.这样就成为一个动态布局. (一) 水平和竖直布局改变 横向: 纵向: ...

随机推荐

  1. AnyEvent::HTTP 实现异步请求

    异步http: jrhmpt01:/root/async# cat a1.pl use LWP::UserAgent; use utf8; use DBI; use POSIX; use HTTP:: ...

  2. Ubuntu系统下在Eclipse中使用真实手机运行调试Android应用

    本文是在Ubuntu下已搭建好JRE+Eclipse+AndroidSDK的环境中进行的. 如果从未进行过如下的操作的话,在运行Android应用时,在设备选择器那里你的手机会显示为一大串" ...

  3. Flex XML搜索、匹配

    - <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx=" ...

  4. HDU 2087 剪花布条 KMP入门

    Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条.计算一下能从花布条中尽可能剪出几块小饰条来呢?   Input ...

  5. 【Linux操作系统分析】设备驱动处理流程

    1 驱动程序,操作系统,文件系统和应用程序之间的关系 字符设备和块设备映射到操作系统中的文件系统,由文件系统向上提供给应用程序统一的接口用以访问设备. Linux把设备视为文件,称为设备文件,通过对设 ...

  6. WLAN和WIFI的区别

    在刚刚为大家介绍的wifi上网是什么意思?文章中为大家介绍了什么wifi无线上网,但大家可能会有这样的疑问,听说最多的应该是WLAN无线上网,很多笔记本电脑使用的都是WLAN无线上网,那么wlan和w ...

  7. c#程序将excel文件转换成xml文件

    要程序你自己去组装去,我只写两个部分,一个是读Excel的部分,然后是写入到xml的1) 从指定的excel读出信息string strConn="provider=Microsoft.Je ...

  8. IIS MIME的 映射 网站有些类型的文件不能通过网页访问

    在iis中能够浏览所有扩展名的文件时,IIS MIME的 映射 您只能在故障排除过程中将通配符映射添加到 IIS MIME 映射中,以作为一种临时解决方案.确定缺少 MIME 类型是问题的原因后,请删 ...

  9. asp.neti 加密三种方式

    public string Get_MD5_Method1(string strSource) { System.Security.Cryptography.MD5 md5 = new System. ...

  10. C指针陷阱

    问题一: #include <stdio.h> int main(int argc, char *argv[]) { ]={ ,,,, }; ); printf(),*(p-)); ; } ...