WPF:从WPF Diagram Designer Part 4学习分组、对齐、排序、序列化和常用功能

在前面三篇文章中我们介绍了如何给图形设计器增加移动、选择、改变大小面板、缩略图、框线选择和工具箱连接等功能,本篇是这个图形设计器系列的最后一篇,将和大家一起来学习一下如何给图形设计器增加分组、对齐、排序、序列化等功能。

WPF Diagram Designer - Part 4

分组:Group, Ungroup

由于WPF不允许一个对象作为多个其他元素的子对象存在,而当移动父对象时,模板也会Unload导致一些问题,所以在这个系列中对分组的实现方式是:当分组一组元素时,内部生成一个Group,这个Group内部其实也是一个DesignerItem对象,只是IsGroup=true而已,在分组时,内部的对象的ParentID都置为这个Group对象的Id

 
public interface IGroupable
{
Guid ID {
get; }
Guid ParentID {
get; set; }
bool IsGroup { get; set; }
}

执行分组时的代码如下:

 

 
private void Group_Executed(object sender, ExecutedRoutedEventArgs e)
{
var items
= from item in this.SelectionService.CurrentSelection.OfType<DesignerItem>()
where item.ParentID == Guid.Empty
select item;

Rect rect
= GetBoundingRectangle(items);

DesignerItem groupItem
= new DesignerItem();
groupItem.IsGroup
= true;
groupItem.Width
= rect.Width;
groupItem.Height
= rect.Height;
Canvas.SetLeft(groupItem, rect.Left);
Canvas.SetTop(groupItem, rect.Top);
Canvas groupCanvas
= new Canvas();
groupItem.Content
= groupCanvas;
Canvas.SetZIndex(groupItem,
this.Children.Count);
this.Children.Add(groupItem);

foreach (DesignerItem item in items)
item.ParentID
= groupItem.ID;

this.SelectionService.SelectItem(groupItem);
}

当我们选择一个分组子对象时,设计器会选择这个分组以及分组的所有子对象

 

 

 
internal void SelectItem(ISelectable item)
{
this.ClearSelection();
this.AddToSelection(item);
}

internal void AddToSelection(ISelectable item)
{
if (item is IGroupable)
{
List
<IGroupable> groupItems = GetGroupMembers(item as IGroupable);

foreach (ISelectable groupItem in groupItems)
{
groupItem.IsSelected
= true;
CurrentSelection.Add(groupItem);
}
}
else
{
item.IsSelected
= true;
CurrentSelection.Add(item);
}
}

 

 

对齐:Align (Left, Right, Top, Bottom, Centered horizontal, Centered vertical)、Distribute (horizontal, vertical)

 

 
private void AlignLeft_Executed(object sender, ExecutedRoutedEventArgs e)
{
var selectedItems
= from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
where item.ParentID == Guid.Empty
select item;

if (selectedItems.Count() > 1)
{
double left = Canvas.GetLeft(selectedItems.First());

foreach (DesignerItem item in selectedItems)
{
double delta = left - Canvas.GetLeft(item);
foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
{
Canvas.SetLeft(di, Canvas.GetLeft(di)
+ delta);
}
}
}
}

 

 
private void AlignHorizontalCenters_Executed(object sender, ExecutedRoutedEventArgs e)
{
var selectedItems
= from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
where item.ParentID == Guid.Empty
select item;

if (selectedItems.Count() > 1)
{
double center = Canvas.GetLeft(selectedItems.First()) + selectedItems.First().Width / 2;

foreach (DesignerItem item in selectedItems)
{
double delta = center - (Canvas.GetLeft(item) + item.Width / 2);
foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
{
Canvas.SetLeft(di, Canvas.GetLeft(di)
+ delta);
}
}
}
}

 

 

排序:Order (Bring forward, Bring to top, Send backward, Send to back)

 

 
private void BringForward_Executed(object sender, ExecutedRoutedEventArgs e)
{
List
<UIElement> ordered = (from item in SelectionService.CurrentSelection
orderby Canvas.GetZIndex(item
as UIElement) descending
select item
as UIElement).ToList();

int count = this.Children.Count;

for (int i = 0; i < ordered.Count; i++)
{
int currentIndex = Canvas.GetZIndex(ordered[i]);
int newIndex = Math.Min(count - 1 - i, currentIndex + 1);
if (currentIndex != newIndex)
{
Canvas.SetZIndex(ordered[i], newIndex);
IEnumerable
<UIElement> it = this.Children.OfType<UIElement>().Where(item => Canvas.GetZIndex(item) == newIndex);

foreach (UIElement elm in it)
{
if (elm != ordered[i])
{
Canvas.SetZIndex(elm, currentIndex);
break;
}
}
}
}
}

序列化:Open, Save

使用XML保存,代码如下:

 
XElement serializedItems = new XElement("DesignerItems",
from item
in designerItems
let contentXaml
= XamlWriter.Save(((DesignerItem)item).Content)
select
new XElement("DesignerItem",
new XElement("Left", Canvas.GetLeft(item)),
new XElement("Top", Canvas.GetTop(item)),
new XElement("Width", item.Width),
new XElement("Height", item.Height),
new XElement("ID", item.ID),
new XElement("zIndex", Canvas.GetZIndex(item)),
new XElement("IsGroup", item.IsGroup),
new XElement("ParentID", item.ParentID),
new XElement("Content", contentXaml)
)
);

读取的时候需要建立Connection

 

 
private void Open_Executed(object sender, ExecutedRoutedEventArgs e)
{
       ... 
foreach (XElement connectionXML in connectionsXML)
{
Guid sourceID
= new Guid(connectionXML.Element("SourceID").Value);
Guid sinkID
= new Guid(connectionXML.Element("SinkID").Value);

String sourceConnectorName
= connectionXML.Element("SourceConnectorName").Value;
String sinkConnectorName
= connectionXML.Element("SinkConnectorName").Value;

Connector sourceConnector
= GetConnector(sourceID, sourceConnectorName);
Connector sinkConnector
= GetConnector(sinkID, sinkConnectorName);

Connection connection
= new Connection(sourceConnector, sinkConnector);
Canvas.SetZIndex(connection, Int32.Parse(connectionXML.Element(
"zIndex").Value));
this.Children.Add(connection);
}
}

常用功能:Cut, Copy, Paste, Delete,Print

 

 
private void Cut_Executed(object sender, ExecutedRoutedEventArgs e)
{
CopyCurrentSelection();
DeleteCurrentSelection();
}

 

 
private void Print_Executed(object sender, ExecutedRoutedEventArgs e)
{
SelectionService.ClearSelection();

PrintDialog printDialog
= new PrintDialog();

if (true == printDialog.ShowDialog())
{
printDialog.PrintVisual(
this, "WPF Diagram");
}
}

 







 本文转自 jingen_zhou 51CTO博客,原文链接:http://blog.51cto.com/zhoujg/517448,如需转载请自行联系原作者


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/392890.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET Core跨域设置

项目中经常会遇到跨域问题&#xff0c;解决方法&#xff1a; 在appsettings.json 文件中添加json项 {"Logging": {"LogLevel": {"Default": "Warning"}},"AllowedHosts": "*","AppCores": "https…

CSS设计指南(读书笔记 - 背景)

本文转自william_xu 51CTO博客&#xff0c;原文链接&#xff1a;http://blog.51cto.com/williamx/1140006&#xff0c;如需转载请自行联系原作者

火车头如何才能设置发布的时候,如果是有html代码就直接的转换掉,互联网上笑话抽取及排重---火车头采集器的使用和MD5算法的应用...

10011311341 吕涛、10011311356李红目的&#xff1a;通过熟悉使用火车头采集器&#xff0c;在网络上采取3万条笑话并进行排重&#xff0c;以此来熟悉web文本挖掘的一些知识。过程&#xff1a;本次学习&#xff0c;主要分成两个部分。第一部分是笑话文本的采集&#xff0c;第二部…

win10上面安装win7的虚拟机怎么相互ping通

最近干了一些很蛋疼的事&#xff0c;这些都是自己踩过的坑&#xff0c;记录下来方便自己以后查阅 首先我的目的就是为了在自己的PC机上面部署一个SVN服务器&#xff0c;然后安装一个客户端&#xff0c;自己写的软件就可以定期入库&#xff0c;做好自己的版本控制&#xff0c;但…

win10用计算机名访问文件夹,win10系统提示你当前无权访问该文件夹的解决方法【图文教程】...

Win10系统下&#xff0c;我们在访问或更改某些系统文件夹时&#xff0c;有时会遇到系统提示“你当前无权访问该文件夹”的情况。那么&#xff0c;遇到这种情况的话&#xff0c;我们该怎么办呢&#xff1f;接下来&#xff0c;小编就向大家分享win10系统提示“你当前无权访问该文…

.Net Micro Framework研究—实现SideShow窗体界面

基于MF系统的Windows SideShow界面是非常炫的&#xff08;如下图&#xff09;。既然微软能用.Net Micro Framework实现这么棒的界面效果&#xff0c;我想我们也能做到。 &#xff08;SideShow模拟器界面和游戏程序中的右键菜单—注意菜单弹出后&#xff0c;其它的界面变暗了&am…

2017年读书计划(一)

前言 这篇博文就暂时不记录技术了&#xff0c;记录下生活。对自己今年2017年做个读书计划安排。 最近在看一部网络剧 - 《花间提壶方大厨》&#xff0c;也许你们会感觉我很无聊&#xff0c;我也是被头条带坏了&#xff0c;每天上班一个小时的地下交通-地铁&#xff0c;就借助上…

音标

音标 oror ds念子音&#xff0c;ts念s音

数据结构与算法---查找算法(Search Algorithm)

查找算法介绍 在java中&#xff0c;我们常用的查找有四种: 顺序(线性)查找 二分查找/折半查找 插值查找斐波那契查找1)线性查找算法 示例&#xff1a; 有一个数列&#xff1a; {1,8, 10, 89, 1000, 1234} &#xff0c;判断数列中是否包含此名称【顺序查找】 要求: 如果找到了&a…

Exchange Server 2007邮箱存储服务器的集群和高可用性技术(上)

高可用性矩阵-->见下图:邮箱服务器高可用性目标: 数据可用性-->保护邮箱数据免于失败和损坏服务可用性-->提高群集实效转移操作 简化群集管理 支持地理分散的群集 支持低成本大邮箱(GB)使用户可以基于业务需要更好的选择容错方案提高解决方案的可用性使用解决方案可…

html设置按钮样式变为椭圆,css border-radius圆形变为椭圆形,位置:绝对

我正在围绕字体真棒图标创建一个圆圈。我的问题是&#xff0c;当我添加position: absolute圆成为一个椭圆。css border-radius圆形变为椭圆形&#xff0c;位置&#xff1a;绝对同样的情况&#xff0c;如果我是设置display: block这里是什么&#xff0c;我想实现的图像 -CONRADU…

《火球——UML大战需求分析》(第1章 大话UML)——1.5 小结和练习

说明&#xff1a; 《火球——UML大战需求分析》是我撰写的一本关于需求分析及UML方面的书&#xff0c;我将会在CSDN上为大家分享前面几章的内容&#xff0c;总字数在几万以上&#xff0c;图片有数十张。欢迎你按文章的序号顺序阅读&#xff0c;谢谢&#xff01;本书已经在各大网…

金陵科技学院计算机开设课程,金陵科技学院各专业介绍

各专业介绍会计学专业(四年制本科) 金融学专业(四年制本科)财务管理专业(四年制本科) 国际经济与贸易专业(四年制本科)市场营销专业(四年制本科)国际商务专业(三年制专科)物流管理专业(三年制专科) 对外汉语专业(四年制本科)古典文献(古籍修复)专业(四年制本科)行政管理(高级秘…

【jQuery Demo】图片由下至上逐渐显示

无意中看到如何实现一张图片从下往上慢慢显现出来这个问题&#xff0c;弄了半天还是从上往下的效果&#xff0c;纠结了&#xff0c;最后还是提问人自己搞定了&#xff01;不过哈哈&#xff0c;又学到一点知识&#xff01; 1.下面是我自己做的效果(按钮可以点哦) 图片由下至上逐…

两个数之和等于第三个数

这是一个很好的算法题&#xff0c;解法类似于快速排序的整理方法。同时&#xff0c;更为值得注意的是这道题是 人人网2014校园招聘的笔试题&#xff0c;下面首先对题目进行描述&#xff1a; 给出一个有序数组&#xff0c;另外给出第三个数&#xff0c;问是否能在数组中找到两个…

html标题前色块,CSS轻松实现色块标题标识

不少网站开始采用韩式风格来建站&#xff0c;这种风格的特点是色彩变化丰富、应用Flash动画合理、结构新颖&#xff0c;最明显的特点就是表格或标题栏常会加上一条横或竖的色带&#xff0c;如图1中圈起来的地方就是这样。(图一)一般人都会想到用Photoshop等软件来完成这样的效果…

101与金根回顾敏捷个人:(13)敏捷个人和敏捷开发

本文更新版本已挪至 http://www.zhoujingen.cn/blog/1726.html ------------------------- 敏捷个人源于工作 自2001初成立了敏捷联盟到现在10年的推广&#xff0c;敏捷开发已日渐成为当前IT行业软件开发的一种主流方法。没有银弹&#xff0c;任何方法都不可能解决所有问题&a…

Exchange server 2010系列教程之三 发送邮件测试

最近有些忙&#xff0c;好几天没有上来写教程了&#xff0c;接着往下写吧。就当是自己的学习笔记&#xff0c;呵呵&#xff0c;有不到之处&#xff0c;还请大家多多指教。 上一篇我们已经把服务器架设好了&#xff0c;那么我们来测试一下发送邮件。 1.首先在AD DC上面新建一个域…

华科的计算机和建筑学哪个强,华中科技大学和华南理工大学相比,谁更占优势?看了也许就知道了...

大学是学生接受教育的过程中非常重要的一个阶段&#xff0c;很多学生都会尽可能在高考中&#xff0c;考出更好的成绩&#xff0c;争取报考一个更好的大学。为了提升教育水平&#xff0c;我国到目前为止建设了超过3000所大学&#xff0c;其中有很多高等院校非常相似&#xff0c;…

uic计算机课程表,美国UIC大学研究生毕业率能达到多少?申请条件、专业课程汇总...

UIC大学也就是伊利诺伊大学芝加哥分校&#xff0c;这所学校始建于1982年&#xff0c;该校拥有东、西两个校区&#xff0c;皆位于美国第二大商业中心芝加哥市的心脏地带&#xff0c;地理位置优势显著&#xff0c;UIC大学有着丰富的教学资源和出色的教学水准&#xff0c;那么接下…