Telerik提供了RadDiagram控件,用于图形元素的旋转,拖拽和缩放.更重要的是,它还拓展了许多绑定的命令(复制,剪切,粘贴,回退等等).

我们可以用来组织自己的图形编辑工具.

Step1.定义图形元素容器(Shape)的基类,继承RadDiagramShape,并重写Serialize和Deserialize方法,来定制将来对象的保存或复制.

    /// <summary>
/// 图形Shape控件
/// </summary>
public class FigureShape : RadDiagramShape
{
public FigureShape()
{
IsConnectorsManipulationEnabled = false;
}
/// <summary>
/// 序列化
/// </summary>
/// <returns></returns>
public override SerializationInfo Serialize()
{
SerializationInfo serializationInfo = base.Serialize(); try
{
var obj = base.Content as FigureBase;
if (obj != null)
{
IFormatter formatter = new BinaryFormatter();
using (var ms = new MemoryStream())
{
formatter.Serialize(ms, obj);
serializationInfo["Figure"] = Convert.ToBase64String(ms.ToArray());
}
}
}
catch (Exception e)
{
throw new Exception("序列化过程失败:" + e.Message);
}
return serializationInfo;
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="serializationInfo"></param>
public override void Deserialize(SerializationInfo serializationInfo)
{
base.Deserialize(serializationInfo); try
{
if (serializationInfo["Figure"] != null)
{
var buffer = Convert.FromBase64String(serializationInfo["Figure"].ToString());
IFormatter formatter = new BinaryFormatter();
using (var ms = new MemoryStream(buffer))
{
Content = formatter.Deserialize(ms);
//绑定Shape坐标和Figure坐标
this.DataContext = Content;
var binding = new Binding("Position") { Mode = BindingMode.TwoWay };
this.SetBinding(PositionProperty, binding);
}
}
}
catch (Exception e)
{
throw new Exception("反序列化过程失败:" + e.Message);
}
}
}

Step2.定义图形元素基类,并支持可序列化

    /// <summary>
/// 图形基类
/// </summary>
[Serializable]
public abstract class FigureBase : NotificationObject
{
/// <summary>
/// 图形位置
/// </summary>
private Point position;
public Point Position
{
get { return position; }
set { position = value; RaisePropertyChanged("Position"); }
}
}

Step3.定义基本图形元素,继承FigureBase,只列出一个示例,不再详述

    [Serializable]
public class StationFig : FigureBase
{
/// <summary>
/// xml节点构造
/// </summary>
/// <param name="node"></param>
public StationFig(XmlNode node)
{
var infoNode = node.ChildNodes.Cast<XmlNode>().FirstOrDefault(s => s.Name == "use");
var xAttri = infoNode.GetAttributeByName("x");
var yAttri = infoNode.GetAttributeByName("y"); this.Position = new Point(double.Parse(xAttri), double.Parse(yAttri));
this.StationType = infoNode.GetAttributeByName("class");
} /// <summary>
/// 厂站类型(220kv,500kv)
/// </summary>
private string stationType;
public string StationType
{
get { return stationType; }
set { stationType = value; RaisePropertyChanged("StationType"); }
}
}

Step4.定义图形元素的样式

    <!--线路样式-->
<DataTemplate DataType="{x:Type svgFigs:LineFig}" >
<Path x:Name="path" StrokeThickness="" Data="{Binding Path}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding LineType}" Value="kv500">
<Setter Property="Stroke" Value="Yellow" TargetName="path"/>
</DataTrigger>
<DataTrigger Binding="{Binding LineType}" Value="kv220">
<Setter Property="Stroke" Value="White" TargetName="path"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<!--厂站样式-->
<DataTemplate DataType="{x:Type svgFigs:StationFig}" >
<Ellipse x:Name="ellipse" Width="" Height="" Fill="Transparent" StrokeThickness=""/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding StationType}" Value="kv500">
<Setter Property="Stroke" Value="Yellow" TargetName="ellipse"/>
</DataTrigger>
<DataTrigger Binding="{Binding StationType}" Value="kv220">
<Setter Property="Stroke" Value="White" TargetName="ellipse"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<!--文本样式-->
<DataTemplate DataType="{x:Type svgFigs:TextFig}" >
<TextBlock x:Name="text" Foreground="White" FontFamily="{Binding FontFamily}" FontSize="{Binding FontSize}" Text="{Binding Text}"/>
</DataTemplate>

Step5.界面编辑工具面板

<telerik:RadDiagram x:Name="diagram"  MinWidth="" BorderThickness=""
Background="Black"
IsBackgroundSurfaceVisible="False"
IsSnapToItemsEnabled="False"
IsSnapToGridEnabled="False"/>

Step6.关键步骤,定义Shape容器中ContentTemplate显示内容

<Style TargetType="{x:Type common:FigureShape}">
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Position" Value="{Binding Position,Mode=TwoWay}"/>
<Setter Property="Content" Value="{Binding}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type common:FigureShape}">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Step7.增加图形元素到面板

        /// <summary>
/// 增加图元到绘图面板
/// </summary>
/// <param name="figure"></param>
private void AddFigureToDiagram(FigureBase figure)
{
var shape = new FigureShape() { DataContext = figure };
diagram.AddShape(shape);
}

编辑工具示例:(支持图元的旋转,移动,缩放,复制粘贴等操作,属性编辑,缩略图导航...)

【Telerik控件学习】-建立自己的图形编辑工具(Diagram)的更多相关文章

  1. 【Telerik控件学习】-制作3D效果的柱状图(ChartView)

    首先,定义柱状图,并设置自定义的DataTemplate <telerik:RadCartesianChart > <telerik:RadCartesianChart.Horizo ...

  2. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  3. DevExpress控件学习总结(转)

    DevExpress控件学习总结   1.Navigation & Layout 1.1 Bar Manager 如果想在窗体或用户控件(user control)上添加工具条(bars)或弹 ...

  4. Android Material Design控件学习(三)——使用TextInputLayout实现酷市场登录效果

    前言 前两次,我们学习了 Android Material Design控件学习(一)--TabLayout的用法 Android Material Design控件学习(二)--Navigation ...

  5. WinFrom 第三方控件 TeleRik控件

    1.首先从工具-拓展与应用中下载安装  TeleRik WinFroms VsExtensions   TeleRik dll文件     2.工具箱控件  将Telerik控件更新过来 3.新建一个 ...

  6. wxPython控件学习之wx.grid.Grid 表格控件

    wxPython控件学习之wx.grid.Grid (包括对GridCellEditor和GridCelRender的扩展,以支持更多的grid cell 样式, 以GridCellColorEdit ...

  7. 转)delphi chrome cef3 控件学习笔记 (二)

    (转)delphi chrome cef3 控件学习笔记 (二) https://blog.csdn.net/risesoft2012/article/details/51260832 原创 2016 ...

  8. PyQt5Day03--程序基本结构之面向对象版本+控件学习

    1.程序基本结构之面向对象版本 (1)开发阶段(自己写好并测试)——设置为模版qto from PyQt5.Qt import * class Window(QWidget): def __init_ ...

  9. DevExpress控件学习总结 z

    1.Navigation & Layout 1.1 Bar Manager 如果想在窗体或用户控件(user control)上添加工具条(bars)或弹出菜单(popup menus),我们 ...

随机推荐

  1. 泛型在Web中的作用

    当我们写网页的时候,常常会有多个DAO,我们要写每次都要写好几个DAO,这样会有点麻烦. 那么我们想要的效果是什么呢??只写一个抽象DAO,别的DAO只要继承该抽象DAO,就有对应的方法了. 要实现这 ...

  2. Java单链表实现

    /** * * 单链表基本操作 * * @author John * */ class LinkList { private Node first; private int pos = 0; publ ...

  3. Mysql中设置默认时间为当前值

    1.直接在创建表时添加该列并声明默认值,如下: CREATE TABLE `table1` ( `id` ) NOT NULL, `createtime` timestamp NULL default ...

  4. eclipse配置maven + 创建maven项目(三)

    上篇博文中我们介绍了maven下载.安装和配置(二),这篇博文我们配置一下eclipse,将它和maven结合,并我们创建一个maven的项目. 准备工作 在eclipse配置maven之前需要我们做 ...

  5. CSS3的颜色渐变效果

    在 animate.css寻找自己想要的动态效果,看到标题Animate.css和按钮Animate it的颜色在逐渐变化,觉得蛮有趣的,把控制变化的相关代码扒了下来,自己分析实现一波. 一开始认为使 ...

  6. codeigniter 去除index.php (nginx,apache) 通用方法

    .htaccess文件配置 1 <IfModule mod_rewrite.c> 2 RewriteEngine On 3 RewriteBase / 4 RewriteCond $1 ! ...

  7. scoke摘要

      登录|注册     关闭 永不磨灭的意志 /* ----------------500G的电影拷到了U盘上,U盘的重量会不会增加?----------------------*/       目录 ...

  8. 三大修饰符static,final,abstract,接口和抽象类的区别

    package com.cityhero.test; public class ThreeModifier { //static静态的 // 概念:static可以修饰方法和属性,被static修的方 ...

  9. Object.defineProperty()方法的用法详解

    Object.defineProperty()函数是给对象设置属性的. Object.defineProperty(object, propertyname, descriptor); 一共有三个参数 ...

  10. AnsiString和String的区别、使用

    16.C/C++语言在CB中的一些特定用法 2)AnsiString是从Delphi中引进来的吗? 答:CB的核心组件VCL是用Object Pascal语言写出的,所以CB的VCL组件的属性有很多都 ...