WPF实现界面动态布局
曾经总认为动态布局是个非常麻烦的问题。是个非常须要功力的问题。可是貌似在.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实现界面动态布局的更多相关文章
- WPF案例 (六) 动态切换UI布局
原文:WPF案例 (六) 动态切换UI布局 这个Wpf示例对同一个界面支持以ListView或者CardView的布局方式呈现界面,使用控件ItemsControl绑定数据源,使用DataTempla ...
- 【源码分享】WPF漂亮界面框架实现原理分析及源码分享
1 源码下载 2 OSGi.NET插件应用架构概述 3 漂亮界面框架原理概述 4 漂亮界面框架实现 4.1 主程序 4.2 主程序与插件的通讯 4.2.1 主程序获取插件注册的服务 4.2 ...
- WPF中的常用布局 栈的实现 一个关于素数的神奇性质 C# defualt关键字默认值用法 接口通俗理解 C# Json序列化和反序列化 ASP.NET CORE系列【五】webapi整理以及RESTful风格化
WPF中的常用布局 一 写在开头1.1 写在开头微软是一家伟大的公司.评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好,应该抛弃对微软和微软的技术的偏见. 1.2 本文内容本文主要内容 ...
- 【腾讯Bugly干货分享】Android动态布局入门及NinePatchChunk解密
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57c7ff5d53bbcffd68c64411 作者:黄进——QQ音乐团队 摆脱 ...
- 界面动态加载时报NullPointException
今天在做环境监测的模拟软件时,登陆页面报NullPointException 一般像我们初始化Button时,是Button btn=(Button)findViewById(R.id.button1 ...
- WPF中的常用布局
一 写在开头1.1 写在开头评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好. 1.2 本文内容本文主要内容为WPF中的常用布局,大部分内容转载至https://blog.csdn.net ...
- android开发学习笔记系列(4)--android动态布局
前言 在做一个有关苏果APP的项目中,但是fuck的是,我完全使用相对布局之后及线性布局之后发现坑爹的事情了,屏幕不能适配,这是多大的痛,意味着,必须使用相应的代码实现动态布局!呵呵,不做项目不知道, ...
- [How to] 动态布局可变高度的cell的应用
1.简介 代码:https://github.com/xufeng79x/DynamicChangeableCell 微博界面,微信和QQ聊天界面,这些界面的布局大都不确定,且每一条消息的高度也不一样 ...
- 3.Dynamic Layout 动态布局。在槽中处理布局
在应用程序中,一个界面的布局基本都是固定的. 在这个实例中,我们把管理布局的代码放在槽中.这样点击一次按钮,触发槽.布局改变一次.这样就成为一个动态布局. (一) 水平和竖直布局改变 横向: 纵向: ...
随机推荐
- java 面试 复习 II
1 break 多重 循环跳出当前循环到上层循环再执行. 如若想跳出多重循环可以使用标号 2 byte,short,char都可以隐含转换为int.可以用在switch 表达式.long和str ...
- JAVA FILE or I/O学习 - File学习
public class FileKnow { public static void main(String[] args) { //构建file对象 ,参数表示文件所在的路径 File file = ...
- BZOJ 2016: [Usaco2010]Chocolate Eating
题目 2016: [Usaco2010]Chocolate Eating Time Limit: 10 Sec Memory Limit: 162 MB Description 贝西从大牛那里收到了 ...
- js 获取前天、昨天、今天、明天、后天的时间
js 获取前天.昨天.今天.明天.后天的时间 2011-05-19 21:03 <html><head><meta http-equiv="Content- ...
- System.Web Namespce
System.Web概述: System.Web是.NET中web应用开发的一个基础类库,定义浏览器与服务器之间的所有操作方法,包括请求输入流(HttpRequest).输出流(HttpRespons ...
- iOS开发之SDWebImage详解
介绍 github地址: https://github.com/rs/SDWebImage 简介 一个异步图片下载及缓存的库 特性: 一个扩展UIImageView分类的库,支持加载网络图片并缓存图片 ...
- 转: cmd和amd的区别
AMD 规范在这里:https://github.com/amdjs/amdjs-api/wiki/AMDCMD 规范在这里:https://github.com/seajs/seajs/issues ...
- How do I Find Out Linux CPU Utilization?
From:http://www.cyberciti.biz/tips/how-do-i-find-out-linux-cpu-utilization.html Whenever a Linux sys ...
- 关于异或(Xor)的一点笔记
因为博弈论里,尤其实在求sg函数时,经常会用到异或运算,所以我就把网上搜到的一些相关知识和自己的一些理解记下来. 如果出现差错,还请指出,谢谢! 异或:可以简称Xor,可以用数学符号⊕表示,计算机就一 ...
- POJ3264——Balanced Lineup(线段树)
本文出自:http://blog.csdn.net/svitter 题意:在1~200,000个数中.取一段区间.然后在区间中找出最大的数和最小的数字.求这两个数字的差. 分析:按区间取值,非常明显使 ...