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

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

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

分组: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,如需转载请自行联系原作者

你可能感兴趣的文章
【vnc】vncserver: couldn't find "xauth" on your PATH 问题
查看>>
扩大Ubuntu的空间
查看>>
Mahout驾驭hadoop之详解
查看>>
java泛型【收藏】
查看>>
Spring Boot自动配置
查看>>
lambda表达式-编译测试
查看>>
Java I/O : Bit Operation 位运算
查看>>
绘制虚线的UIView
查看>>
【Oracle】oracle的LAG和LEAD分析函数
查看>>
HDU 1006 Tick and Tick 时钟指针问题
查看>>
C编程常见问题总结
查看>>
使用最新版SDWebImage
查看>>
数据仓库专题(5)-如何构建主题域模型原则之站在巨人的肩上(二)NCR FS-LDM主题域模型划分...
查看>>
数据仓库3NF基础理论和实例
查看>>
backsolve & fowardsolve 解特殊方程 (上三角或下三角系数为0的方程)
查看>>
android数据绑定框架介绍
查看>>
Oracle SQL : delete from (query), delete which table's row?
查看>>
hdu 1009 FatMouse&#39; Trade
查看>>
Filter过滤器
查看>>
Percona-Server/MySQL响应时间统计
查看>>