您的位置:首页 > 其它

WPF实现界面动态布局

2014-05-27 18:52 309 查看
以前总觉得动态布局是个很麻烦的问题,是个很需要功力的问题。但是貌似在.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);
}

}


至此,我们完成了动态布局的设定和保存,尝试一下吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: