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. eclipse复制到IDEA中文不匹配,编译失败

    今天使用把eclipse的包复制到Intellij Idea下,结果在编译的时候,它说我的数据是GBK,而Idea默认的数据是UTF-8,因此出错了... 解决:在项目中直接把对象的encoding. ...

  2. Javascript-正则表达式-开发中的使用.

    -- "(-1~99)之间 -1表示无限次!" pattern="^((-1)|([0-9]{0,2}))$" -- "(0~99.99)之间 的金额 ...

  3. 从content-type设置看Spring MVC处理header的一个坑

    我们经常需要在HttpResponse中设置一些headers,我们使用Spring MVC框架的时候我们如何给Response设置Header呢? Sooooooooooooo easy, 看下面的 ...

  4. YYHS-NOIP2017Training0921-逆光

    题目描述 有一束光/那瞬间/是什么痛得刺眼/你的视线是谅解/为什么舍不得熄灭/我逆着光却看见/那是泪光/那力量/我不想再去抵挡/面对希望/逆着光/感觉爱存在的地方/一直就在我身旁 Descriptio ...

  5. JVM菜鸟进阶高手之路四

    转载请注明原创出处,谢谢! 由于很多的jvm分析最好是基于gc日志的,所以添加参数如下即可: -verbose:gc -XX:+HeapDumpOnOutOfMemoryError -XX:+Prin ...

  6. iOS连续dismiss几个ViewController的方法

    原文链接:http://blog.csdn.net/longshihua/article/details/51282388 presentViewController是经常会用到的展现ViewCont ...

  7. hive参数配置

    CLI参数 两种修改方式: 1)启动时 hive --hiveconf  hive.cli.print.current.db=true 2)修改当前用户home目录下 .hiverc文件,hive c ...

  8. 一次生产环境下MongoDB备份还原数据

    最近开发一个版本的功能当中用到了MongoDB分页,懒于造数据,于是就研究了下从生产环境上导出数据到本地来进行测试. 研究了一下,发现MongoDB的备份还原和MySQL语法还挺类似,下面请看详细介绍 ...

  9. Bear and Floodlight 状态压缩DP啊

    Bear and Floodlight Time Limit: 4000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u ...

  10. 【微信小程序】调用wx.request接口需要注意的问题

    写在前面 之前写了一篇<微信小程序实现各种特效实例>,上次的小程序的项目我负责大部分前端后台接口的对接,然后学长帮我改了一些问题.总的来说,收获了不少吧! 现在项目已经完成,还是要陆陆续续 ...