首页 > 代码库 > 【Telerik控件学习】-建立自己的图形编辑工具(Diagram)

【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);            }        }    }
View Code

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"); }        }    }
View Code

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"); }        }    }
View Code

Step4.定义图形元素的样式

技术分享
    <!--线路样式-->    <DataTemplate DataType="{x:Type svgFigs:LineFig}" >        <Path x:Name="path" StrokeThickness="2" Data=http://www.mamicode.com/"{Binding Path}"/>        <DataTemplate.Triggers>            <DataTrigger Binding="{Binding LineType}" Value=http://www.mamicode.com/"kv500">                <Setter Property="Stroke" Value=http://www.mamicode.com/"Yellow" TargetName="path"/>            </DataTrigger>            <DataTrigger Binding="{Binding LineType}" Value=http://www.mamicode.com/"kv220">                <Setter Property="Stroke" Value=http://www.mamicode.com/"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=http://www.mamicode.com/"kv500">                <Setter Property="Stroke" Value=http://www.mamicode.com/"Yellow" TargetName="ellipse"/>            </DataTrigger>            <DataTrigger Binding="{Binding StationType}" Value=http://www.mamicode.com/"kv220">                <Setter Property="Stroke" Value=http://www.mamicode.com/"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>
View Code

Step5.界面编辑工具面板

技术分享
<telerik:RadDiagram x:Name="diagram"  MinWidth="500" BorderThickness="1"Background="Black"IsBackgroundSurfaceVisible="False"IsSnapToItemsEnabled="False" IsSnapToGridEnabled="False"/>
View Code

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

技术分享
<Style TargetType="{x:Type common:FigureShape}">      <Setter Property="BorderBrush" Value=http://www.mamicode.com/"{x:Null}"/>      <Setter Property="Background" Value=http://www.mamicode.com/"Transparent"/>      <Setter Property="Position" Value=http://www.mamicode.com/"{Binding Position,Mode=TwoWay}"/>       <Setter Property="Content" Value=http://www.mamicode.com/"{Binding}"/>       <Setter Property="Template">           <Setter.Value>                <ControlTemplate TargetType="{x:Type common:FigureShape}">                      <ContentPresenter/>                 </ControlTemplate>            </Setter.Value>        </Setter></Style>    
View Code

Step7.增加图形元素到面板

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

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

 


 

 

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