在使用Netron之前,我们要先来了解一下Netron的三个关键类:Shape、Connection、Connector。您可以在 NetronGraphLibrary文件夹下发现他们。这三个类均继承自Entity类。下面我们简要介绍Entity类的基本模块,先看Entity 类的代码。


using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.IO;
using System.Security;
using System.Security.Permissions;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using Netron.GraphLib.UI;
using Netron.GraphLib.Interfaces;
using Netron.GraphLib.Attributes;
using Netron.GraphLib.Configuration;
namespace Netron.GraphLib
{
///
/// Abstract base class for everything that participates in the diagram/graph (connection, connector

///
[Serializable] public abstract class Entity : IEntity, IDisposable, ISerializable
{
#region Events
///
/// Occurs when the mouse is pressed on this entity
///
public event MouseEventHandler OnMouseDown;
///
/// Occurs when the mouse is released while above this entity
///
public event MouseEventHandler OnMouseUp;
///
/// Occurs when the mouse is moved while above this entity
///
public event MouseEventHandler OnMouseMove;
#endregion
#region Fields
///
/// the layer to which the entity belongs,
/// the default layer is a static unique layer defined in the GraphAbstract.
///
private GraphLayer mLayer;
///
/// volatile all-purpose tag
///
[NonSerialized] private object mTag;
///
/// whether to recalculate the shape size, speed up the rendering
///
private bool mRecalculateSize ;
///
/// the property bag
///
[NonSerialized] private PropertyBag mBag;
///
/// default blue mPen, speeds up rendering
/// Note that the Pen is not serialzable!
///
[NonSerialized] private Pen mBluePen;
///
/// default black mPen, speeds up rendering
///
[NonSerialized] private Pen mBlackPen;
///
/// the mPen's width
///
private float mPenWidth = 1F;
///
/// default mPen
///
[NonSerialized] private Pen mPen;
///
/// whether the entity is reset
///
private bool mIsGuiReset;
///
/// the font family
///
private string mFontFamily = "Verdana";
///
/// whether the entity is selected
///
private bool mIsSelected;
///
/// whether this entity is being hovered
///
private bool mIsHovered ;
///
/// the unique identitfier
///
private Guid mUID ;
///
/// mText or label
///
private string mText = "[Not set]";
///
/// whether to show the mText label
///
private bool mShowLabel = true;
///
/// the default mText color
///
private Color mTextColor = Color.Black;
///
/// the default font size in points
///
private float mFontSize = 7.8F;
///
/// the default font for entities
///
private Font mFont;
///
/// the mSite of the entity
///
[NonSerialized] private IGraphSite mSite;
#endregion
#region Properties
///
/// Gets or sets the pen-object to paint and draw
///
public Pen Pen
{
get{return mPen;}
set{mPen = value;}
}
///
/// Gets the property-bag
///
///
protected PropertyBag Bag
{
get{return mBag;}
}
///
/// Gets or sets whether the next painting roun will have to recalculate the size of the entity
///
protected bool RecalculateSize
{
get{return mRecalculateSize;}
set{mRecalculateSize = value;}
}
///
/// Gets the default black mPen for drawing text and lines
///
protected Pen BlackPen
{
get{return mBlackPen;}
}
///
/// Gets or sets the font-family used by derived class to draw and paint on the canvas
///
protected virtual string FontFamily
{
get{return mFontFamily;}
set{mFontFamily = value;}
}
///
/// Gets the layer ths shape is on. If null, the shape is in the default layer.
///
///
///
public GraphLayer Layer
{
get
{
return mLayer;
}
}
///
/// Gets or sets a general purpose tag object
///
public object Tag
{
get{return mTag;}
set{mTag = value;}
}
///
/// Gets or sets the mPen width
///
[GraphMLData]public float PenWidth
{
get{return mPenWidth;}
set{mPenWidth = value;}
}
///
/// Gets or sets whether the shape label should be shown.
///
[GraphMLData]public virtual bool ShowLabel
{
get
{
return mShowLabel;
}
set
{
mShowLabel=value; this.Invalidate();
}
}
///
/// Allows to view/change the properties of the shape, most probably on double-clicking it.
///
public virtual PropertyBag Properties
{
get{return mBag;}
}
///
/// Gets or sets the entity label
///
[GraphMLData]public virtual string Text
{
get
{
return mText;
}
set
{
if (value!=null) mText=value;
}
}
///
/// Gets or sets the mSite of the entity
///
public IGraphSite Site
{
get{return mSite;}
set{mSite = value;}
}
///
/// Tells wether the entity (shape) is selected
///
public virtual bool IsSelected
{
set { Invalidate(); mIsSelected = value; Invalidate(); }
get { return mIsSelected; }
}
///
/// Gets or sets whether the entity's UID is reset
///
///
protected internal virtual bool IsGuiReset
{
get{return mIsGuiReset;}
set{mIsGuiReset = value;}
}
///
/// Gives true if the mouse is hovering over this entity
///
protected internal virtual bool IsHovered
{
set { Invalidate(); mIsHovered = value; Invalidate(); }
get { return mIsHovered; }
}
///
/// Gets or sets the mText color
///
public virtual Color TextColor
{
get
{
return mTextColor;
}
set
{
mTextColor=value;
}
}
///
/// Gets or sets the font size of the mText
///
protected virtual float FontSize
{
get
{
return mFontSize;
}
set
{
mFontSize=value;
}
}
///
/// Gets or sets the font to be used when drawing text-data
///
protected Font Font
{
get{return this.mFont;}
set
{
this.mFont = value;
this.mFontFamily = value.FontFamily.ToString();
this.mFontSize = value.Size;
}
}
///
/// Gets or sets the unique identifier for the shape.
///
public Guid UID
{
get
{
return mUID;
}
set{mUID = value;}
}
///
/// Gets the Summary for this entity
///
public Summary Summary
{
get
{
return this.Site.GetSummary(this);
}
}
///
/// Gets the tracker of the entity
///
public virtual Tracker Tracker
{
get{return null;}
set{}
}
#endregion
#region Constructors
///
/// Constructor for the entity class, initializes a new GUID for the entity
///
protected Entity()
{
InitEntity();
}
///
/// Creates a new entity, specifying the mSite
///
///
protected Entity(IGraphSite site)
{
InitEntity();
this.mSite = site;
}
///
/// Deserialization constructor
///
///
///
protected Entity(SerializationInfo info, StreamingContext context)
{
InitEntity();
//overwrite some members with the serialized data
this.mUID = new Guid(info.GetString("mUID"));
this.mText = info.GetString("mText");
this.mShowLabel = info.GetBoolean("mShowLabel");
this.mTextColor = (Color) info.GetValue("mTextColor",typeof(Color));
try
{
this.mFont = (Font) info.GetValue("mFont", typeof(Font));
}
catch
{
//font is set by default in the member definition
}
//this.mIsSelected = info.GetBoolean("mIsSelected");
}
#endregion
#region Methods
///
/// IDispose implementation
///
public void Dispose()
{
this.mFont.Dispose();
this.mPen.Dispose();
this.mBlackPen.Dispose();
this.mBluePen.Dispose();
}
///
/// Sets the layer the entity belongs to
///
///
protected virtual void SetLayer(GraphLayer layer)
{
mLayer = layer;
return;
}
///
/// Sets the shape in a layer.
/// Use "default" to set the shape in the default layer.
///
///
public void SetLayer(string name)
{
if(name.CompareTo("Default")==0)
{
SetLayer(GraphAbstract.DefaultLayer);
}
else
{
SetLayer(Site.Abstract.Layers[name]);
}
}
///
/// Sets the shape in a layer.
/// Layer 0 is the default layer.
///
///
public void SetLayer(int index)
{
if(index==0)
{
SetLayer(GraphAbstract.DefaultLayer);
}
else
{
index--;//the collection starts at 0
SetLayer(Site.Abstract.Layers[index]);
}
}
///
/// Determines which properties are accessible via the property grid
///
///
///
protected virtual void GetPropertyBagValue(object sender, PropertySpecEventArgs e)
{
switch(e.Property.Name)
{
case "Text": e.Value=this.mText;break;
case "ShowLabel": e.Value=this.ShowLabel; break;
}
}
///
/// Sets the values passed by the property grid
///
///
///
protected virtual void SetPropertyBagValue(object sender, PropertySpecEventArgs e)
{
switch(e.Property.Name)
{
case "ShowLabel": this.ShowLabel=(bool) e.Value; break;
case "Text":
//use the logic and the constraint of the object that is being reflected
if(e.Value.ToString() != null)
{
this.mText=(string) e.Value;
}
else
MessageBox.Show("Not a valid label","Invalid label",MessageBoxButtons.OK,MessageBoxIcon.Warning);
break;
}
this.Invalidate();
}
///
/// When overriden, allows user defined entities to get custom properties
///
public virtual void AddProperties()
{
return;
}
///
/// Initializes the class. This method is necessary when deserializing since various elements like
/// the Pen cannot be serialized to file and have to be, hence, set after deserialization.
///
protected internal virtual void InitEntity()
{
mLayer = GraphAbstract.DefaultLayer;
mBluePen= new Pen(Brushes.DarkSlateBlue,1F);
mBlackPen = new Pen(Brushes.Black,1F);
mUID = Guid.NewGuid();
mRecalculateSize = false;
mFont = new Font(mFontFamily,mFontSize,FontStyle.Regular,GraphicsUnit.Point);
mPen=new Pen(Brushes.Black, mPenWidth);
mLayer = GraphAbstract.DefaultLayer;//everything is initially in the default (static) layer
mBag=new PropertyBag(this);
try
{
mBag.GetValue+=new PropertySpecEventHandler(GetPropertyBagValue);
mBag.SetValue+=new PropertySpecEventHandler(SetPropertyBagValue);
mBag.Properties.Add(new PropertySpec("Text",typeof(string),"Appearance","The text attached to the entity","[Not set]"));
mBag.Properties.Add(new PropertySpec("ShowLabel",typeof(bool),"Appearance","Gets or sets whether the label will be shown."));
// PropertySpec spec=new PropertySpec("MDI children",typeof(string[]));
// spec.Attributes=new Attribute[]{new System.ComponentModel.ReadOnlyAttribute(true)};
// mBag.Properties.Add(spec);
//AddProperties(); //add the user defined shape properties
}
catch(Exception exc) //TODO: catch only those exceptions that you can handle gracefully
{
Trace.WriteLine(exc.Message, "Entity.InitEntity");
}
catch
{
Trace.WriteLine("Non-CLS compliant exception caught.", "Entity.InitEntity");
}
}
///
/// creates the actual visual element on screen
///
///
public abstract void Paint(Graphics g);
///
/// Gets the cursor for the current position of the mouse
///
///
///
public abstract Cursor GetCursor(PointF p);
///
/// GraphAbstract delete method; deletes the entity from the plex
///
internal protected abstract void Delete();
///
/// Says wether, for the given rectangle, the underlying shape is contained in it.
///
///
///
public abstract bool Hit(RectangleF r);
///
/// Invalidating refreshes part or all of a control
///
public abstract void Invalidate();
///
/// Allows to paints additional things like the clickable elements on shapes
/// independently of the shape's design
///
///
public abstract void PaintAdornments(Graphics g);
///
/// Paints the tracker of the entity
///
///
public void PaintTracker(Graphics g)
{
if(this.IsSelected) this.Tracker.Paint(g);
}
///
/// Regenerates a GUID for this entity
///
public void GenerateNewUID()
{
mUID=Guid.NewGuid();
mIsGuiReset=true;
}
///
/// Raises the mouse down event
///
///
internal virtual void RaiseMouseDown(MouseEventArgs e)
{
if(OnMouseDown != null) OnMouseDown(this, e);
}
///
/// Raises the mouse up event
///
///
internal void RaiseMouseUp(MouseEventArgs e)
{
if(OnMouseUp != null) OnMouseUp(this, e);
}
internal void RaiseMouseMove(MouseEventArgs e)
{
if(OnMouseMove!=null) OnMouseMove(this,e);
}
#endregion
#region ISerializable Members
///
/// ISerializable implementation
///
/// the serialization info
/// the streaming context
[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter=true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("mUID",this.mUID.ToString());
info.AddValue("mTextColor",this.mTextColor,typeof(Color));
info.AddValue("mText",this.mText);
info.AddValue("mShowLabel",this.mShowLabel);
info.AddValue("mFont", this.mFont, typeof(Font));
//additional check in case we're making a deep copy of a bundle
if(mLayer==null)
info.AddValue("mLayer","Default");
else
info.AddValue("mLayer",this.mLayer.Name);
}
///
/// Post-deserialization actions
///
public virtual void PostDeserialization()
{
//add the properties
this.AddProperties();
}
#endregion
}
}
可以看到这个基本类多继承接口IEntity, IDisposable, ISerializable。类本身可以做的3个基本鼠标事件支持,以及实体大小等字段,还有序列化方法等等。
下面给出一个三个类的实例图
Shape即为图像所画出的实体,代码太多就不贴了不好意思哈。
字段介绍: 注意看这个字段mRectangle这个字段十分重要,大致作用是shape的本体宿主,你可以通过这个取得shape的坐标以及宽和高。
方法介绍:这里不能不说Paint方法,这个方法是每种shape都要override的方法,其主要作用是绘制图像,不同图像的很大区别也在这个方法的内容不同。
Connection即为图像的连线,代码太多就不贴了不好意思哈
字段介绍 :private Connector mFrom ;private Connector mTo;这两个是Connector(待会介绍这个类)引用,这是保存连线的开始节点和结束节点。private Color mLineColor 连线的颜色。private DashStyle mLineStyle连线的样式,可选值是枚举类型的,比如点,还是实心线等。ConnectionEnd mLineEnd,连线结束头的样子,可选值是枚举类型,例如可选小箭头型。private Tracker mTracker; 这个Tracker类放到下一篇介绍
方法介绍:Invalidate(),刷新自身的方法,另外一个重要的方法是Delete方法。其余方法读者自己可以去研究,我因没有多深入,在此不多说了。
Connector即为图像身边的小灰色方块点,这些点的作用是连线的接头,注意Connection类中含有Connector mFrom 和Connector mTo两个字段。注意Connector仅仅存在于shape类内,自己不可独立存在。也即shape类组合Connector,这里关系类似骑车轮胎和 汽车的关系一样。
Connector也仅仅一个类,如果读者愿意完全可以自己实现一个Connector替换之,下面是它的代码。































- making the connector blink or flash when hit

- show an extensive information box when hovered

- attach a status message when hovered

- differentiate different connector on their propagation type or their parnet/child relation












































































































































































































































































































































































































































































































































































字段介绍:这里介绍有几个重要的字段:mBelongsTo 此字段作用是保存本点所属于那个shape,private mConnections 此字段作用是保存本点所连接的所以connection,mAllowNewConnectionsFrom 此字段作用是确定本点是否允许新的线画出, mAllowNewConnectionsTo 此字段作用是是否允许新的线连入本点。
方法暂不了解,有兴趣读者可以自己去看。