• 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); } }


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


  • 相关阅读:
    设计模式之责任链模式(Chain of Responsibility )
    Cubieboard2裸机开发之(二)板载LED交替闪烁
    Cubieboard2裸机开发之(一)点亮板载LED
    A20(Cubieboard2)启动过程浅析
    入手Cubieboard2之制作最小Linux系统
    ARM Linux启动代码分析
    Linux设备驱动剖析之Input(四)
    Linux设备驱动剖析之Input(三)
    Linux设备驱动剖析之Input(二)
    Linux设备驱动剖析之Input(一)
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5170511.html
Copyright © 2020-2023  润新知