WPF:从WPF Diagram Designer Part 4学习分组、对齐、排序、序列化和常用功能
2010-08-19 15:03
721 查看
在前面三篇文章中我们介绍了如何给图形设计器增加移动、选择、改变大小及面板、缩略图、框线选择和工具箱和连接等功能,本篇是这个图形设计器系列的最后一篇,将和大家一起来学习一下如何给图形设计器增加分组、对齐、排序、序列化等功能。
执行分组时的代码如下:
当我们选择一个分组子对象时,设计器会选择这个分组以及分组的所有子对象
读取的时候需要建立Connection
欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]
WPF Diagram Designer - Part 4
分组:Group, Ungroup
由于WPF不允许一个对象作为多个其他元素的子对象存在,而当移动父对象时,模板也会Unload导致一些问题,所以在这个系列中对分组的实现方式是:当分组一组元素时,内部生成一个Group,这个Group内部其实也是一个DesignerItem对象,只是IsGroup=true而已,在分组时,内部的对象的ParentID都置为这个Group对象的Idpublic 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"); } }
欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]
相关文章推荐
- WPF:从WPF Diagram Designer Part 4学习分组、对齐、排序、序列化和常用功能
- WPF:从WPF Diagram Designer Part 3学习如何给设计器增加连接线功能
- WPF:从WPF Diagram Designer Part 3学习如何给设计器增加连接线功能
- WPF:从WPF Diagram Designer Part 1学习控件模板、移动、改变大小和旋转
- WPF:从WPF Diagram Designer Part 1学习控件模板、移动、改变大小和旋转
- WPF:从WPF Diagram Designer Part 1学习控件模板、移动、改变大小和旋转
- WPF and Silverlight 学习笔记(二十五):使用CollectionView实现对绑定数据的排序、筛选、分组
- WPF and Silverlight 学习笔记(二十五):使用CollectionView实现对绑定数据的排序、筛选、分组
- [转]WPF and Silverlight 学习笔记(二十五):使用CollectionView实现对绑定数据的排序、筛选、分组
- WPF:从WPF Diagram Designer Part 2学习面板、缩略图、框线选择和工具箱-上
- WPF:从WPF Diagram Designer Part 2学习面板、缩略图、框线选择和工具箱-下
- jQuery框架学习第十天:实战jQueryUI常用功能
- ASP.NET MVC学习---(八)三个比较常用的方便的功能
- WPF 视图分组排序
- 学习Linux笔记(二)-常用+查找排序
- 从零开始学习jQuery (十) jQueryUI常用功能实战
- OJ中常用的功能函数(排序)
- MYSQL-实现ORACLE 和SQLserver数据中- row_number() over(partition by ) 分组排序功能
- Java学习-常用排序稳定性分析
- ASP.NET MVC学习---(八)三个比较常用的方便的功能