【Telerik控件学习】-建立自己的图形编辑工具(Diagram)

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="2" 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="20" Height="20" Fill="Transparent" StrokeThickness="3"/>
        <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="500" BorderThickness="1"
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);
        }

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

时间: 2024-11-13 09:46:59

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

Silverlight Telerik控件学习:主题Theme切换html教程

telerik的RadControls for Silverlight内置了以下几种主题样式: Office Black - 这是默认值,无需加载其它任何dll文件. Office Blue - 需要引用 Telerik.Windows.Themes.Office_Blue.dll. Office Silver - 需要引用 Telerik.Windows.Themes.Office_Silver.dll. Summer - 需要引用 Telerik.Windows.Themes.Summer.

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

首先,定义柱状图,并设置自定义的DataTemplate <telerik:RadCartesianChart > <telerik:RadCartesianChart.HorizontalAxis> <telerik:LinearAxis Minimum="0"/> </telerik:RadCartesianChart.HorizontalAxis> <telerik:RadCartesianChart.VerticalAxis

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

wxPython控件学习之wx.grid.Grid (包括对GridCellEditor和GridCelRender的扩展,以支持更多的grid cell 样式, 以GridCellColorEditor为例) wx.Grid 及其相关的类是用来显示和编辑类表格样式的数据.该控件为显示,编辑数据源提及交互供了丰富的特征. wx.GridTableBase类控制要显示的实际数据.可以call CreateGrid()产生一个该类的实例对象. wx.GridCellRenderer 基类,负责对单元

CComboBox(组合框)控件 学习要点

CComboBox(组合框)控件 CComboBox类常用成员 CComboBox插入数据 CComboBox删除数据 CComboBox运用示例   一.CComboBox控件常用属性    Disabled    Visible    type    数据   二.CComboBox类常用成员   ((CComboBox*)GetDlgItem(IDC_COMBO1))//获取组合框对象指针,这样可以不关联控件变量,也可以操作组合框对象 CComboBox::ResetContent//清空

telerik 控件 SCRIPT5007: 无法获取未定义或 null 引用的属性“documentElement” (IE 文档模式)

IE对盒模型的渲染在 Standards Mode和Quirks Mode是有很大差别的,在Standards Mode下对于盒模型的解释和其他的标准浏览器是一样,但在Quirks Mode模式下则有很大差别,而在不声明Doctype的情况下,IE默认又是Quirks Mode.所以为兼容性考虑,我们可能需要获取当前的文档渲染方式.document.compatMode正好派上用场,它有两种可能的返回值:BackCompat和CSS1Compat.BackCompat:标准兼容模式关闭.浏览器客

DbNetGrid控件学习教程及下载使用指南

DbNetGrid是龙博方案网的旗帜产品.它是一款基于网页的报告工具,它能简单地在浏览器中展示数据库信息.通过DbNetGrid,您能在不编写任何代码的情况下搜索.导航.分类.编辑.复制.打印以及导出数据库信息.是一款完全压缩的.用于内网与互联网开发的HTML网格控件.它被设计用来实现能在浏览器环境中展示与更新数据库信息的快速灵活的方法.DbNetGrid能完全开发IE5及更高版本浏览器的功能 具体功能: 搜索.导航.分类.更新.添加.删除.导出.上传.连接.嵌入.打印.复制以及更多-- 不需要

GUI 控件学习一(C#)

代码片段: using UnityEngine; using System.Collections; public class SkinTest : MonoBehaviour { public Texture imgbtn; private string textContent ="Textfield"; private string passwordToEdit ="PasswordField"; private string textAreaToEdit =

对象与控件如何建立关联

从CListCtrl派生自己的类,对象与控件如何建立关联? 一般有三种方式:1.窗口类中定义CMyList对象,在窗口初始化时用该对象的Create函数创建:2.对话框资源上放一个ListCtrl控件,窗口类中定义CMyList对象,在窗口初始化时用该对象的SubclassDlgItem与控件建立关联.3.对话框资源上放一个ListCtrl控件,用VC给控件添加CListCtrl型的关联变量,再手动把变量类型该成CMyList.

Telerik 控件的汉化-检索当前控件的键值对

(第一次随手写了个东东发现被各种转载,傻笑下,那就顺便把下午试验出来的方式给大家分析下吧,妹纸说难得被转载一次,鼓励我多写点) telerik每个版本内置的英文是有差异的,然后很多资料的内置键值对都是不全的,下面的方法是用来查询当前控件的所有键值对. 这个是借鉴资料山寨来的思路. 核心思路其实就是新增一个继承LocalizationManager,CustomLocalizationManager类,然后重写这个类的语言的时候获取出所有键值对. 1.新建一个CustomLocalizationM