博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF:从WPF Diagram Designer Part 4学习分组、对齐、排序、序列化和常用功能
阅读量:6719 次
发布时间:2019-06-25

本文共 5452 字,大约阅读时间需要 18 分钟。

  在前面三篇文章中我们介绍了如何给图形设计器增加及和等功能,本篇是这个图形设计器系列的最后一篇,将和大家一起来学习一下如何给图形设计器增加分组、对齐、排序、序列化等功能。

2009112317381541.png

分组: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
"
);
}
}

 

 

欢迎转载,转载请注明:转载自 [ ]

你可能感兴趣的文章
【拾贝】版本控制-git 建立Team项目
查看>>
和为S的连续正数序列
查看>>
孩子们的游戏(圆圈中最后剩下的数)
查看>>
MySQL的AB复制
查看>>
Mysql调优:
查看>>
批量修改root密码#shell脚本
查看>>
Linux命令学习记录(四)
查看>>
Oracle日常维护操作笔记(一)
查看>>
网管必懂的几个概念
查看>>
puppet 部署
查看>>
ISCSI文件存储
查看>>
求助:关于windows飞信机器人的问题
查看>>
我的友情链接
查看>>
关于初步搭建完成SSH环境之后,JUnit test 测试成功,页面测试时:@Resource 注入的dao为null...
查看>>
更强大的 code generator 自定义工具
查看>>
PHP 在大多数 Unix 平台
查看>>
革命老区江西省赣州市开发区政府暴力强拆
查看>>
extmail搭建
查看>>
FlowChart.NET中如何更改撤消或重做的属性
查看>>
【进阶篇】Android学习笔记——TextInputLayout
查看>>