WPF实现界面动态布局

WPF实现界面动态布局

大家好,又见面了,我是全栈君。

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

 

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

 

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

1、动态画线

2、动态new控件

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

4、线和控件是可删除的

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

 

 

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

比如我要画一条线。那么左键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); } }

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/116120.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Pycharm配置Pyqt5(精细版)[通俗易懂]

    Pycharm配置Pyqt5(精细版)[通俗易懂]Pycharm配置Pyqt5(精细版)前言最近入手了一些关于Qt的项目开发,需要用到Pycharm与Pyqt5的一个结合,当然在安装时也是有一些小坑的,下面我来为大家分享一下在Pycharm中配置Pyqt5的过程。环境配置1、创建虚拟环境:condacreate-nmy_pyqtpython=x.x命令创建python版本为x.x(本人用的3.7)、名字为my_pyqt的虚拟环境。my_pyqt文件可以在Anaconda安装目录envs文件下找到。2、切换/激活虚拟环境:conda

  • 关于列表转字符串这个过程的曲折

    关于列表转字符串这个过程的曲折

  • 2019js前端面试最全集合

    2019js前端面试最全集合一、html和css部分1、如何理解CSS的盒子模型?标准盒子模型:宽度=内容的宽度(content)+border+padding低版本IE盒子模型:宽度=内容宽度(content+border+padding)2、BFC?什么是BFCBFC(BlockFormattingContext)格式化上下文,是Web页面中盒模型布局的CSS…

  • eclipse中文插件如何安装_eclipse不显示svn插件

    eclipse中文插件如何安装_eclipse不显示svn插件1、在eclipse中下载插件,地址如下:Name:Subclipse1.2.x(Eclipse3.2+)   URL: http://subclipse.tigris.org/update_1.2.xName:Subclipse1.0.x(Eclipse3.0/3.1)   URL: http://subclipse.tigris.org/up

    2022年10月11日
  • 详解自动化运维平台的构建过程[通俗易懂]

    详解自动化运维平台的构建过程[通俗易懂]2013年,我加入了聚美优品,当时成都团队仅有四五个人,负责一些辅助系统的日常运维,比如查查日志等。随着公司规模逐渐的扩大,一些重要的业务往成都迁移,这对成都团队是一个非常大的挑战。业务部署最开始是手工的,我们逐渐觉得应该有一个平台来满足我们的工作,所以我们打造了一个运维平台。本文将围绕平台里有关自动化的东西做一个介绍,当然我们是一个小团队,不足的地方请大家指正。传统运维带来的坑说到运维自动化,前…

  • 对称矩阵的压缩存储

    对称矩阵的压缩存储

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号