Silverlight学习-创建一个信息系统中趋势曲线图库(二)

        上一篇中介绍了动态添加Silverlight绘图元素,由于这些绘图元素的使用并不简洁,接着就要构造基本图形库了。
        工程应用中的图形库,基本有两种构建方式:一种是类似Win Form中的Graphics类,绘制图形简洁,但这种图形不是以“元素”的形式出现,绘制之后图形元素不能被索引,它自身没有属性或事件的概念,因此这种方式适用于“一次绘制好后,只供用户观看”的场合,例如背景图的绘制、示意曲线的绘制等;另一种是类似Silverlight中的图形绘制方式,各图形元素是一个真正的类,自身有属性或事件,可以被索引,相比第一种情况,这是一种“重量级”的绘图方式,适用于“随时捕捉图形,并对其施加操作”的场合,例如绘制工作流图等。本文称第一种库为图形绘制库,称第二种库为图形元素库。本文只关注图形绘制库的建立。
       本文还有一个目的,尽量消除在WinForm和Silverlight中绘制图形的不同,同一套代码,几乎不用修改就能在WinForm和Silverlight中绘制出相同的图形。由于Silverlight应用中不能随便引用其他C#类库,所以Silverlight应用与其他应用中的通用功能,只能通过代码共用。

        Graphics类是一个“天然”的编制图形绘制库,本文将以它为基础,主要对Silverlight中的绘图元素进行改造。由于Silverlight独立部署的特性,使Silverlight与WinForm的绘图类之间无任何共有部分,但是为达到“同一代码,两处通用”的目的,两者的绘图类都不能使用,必须重新定义一套接口及相关辅助类。下图是本文图形绘制库中所涉及的类。

IGraphBase是一个接口类,它定义了类似Graphics类中的各类图形绘制方法,LinePen、PaintBrush等类是图形绘制过程中用到的辅助类,例如LinePen包装了Pen类等。WinFormGraphics和SilverlightGraphics实现了IGraphBase接口,分别用于在WinForm和Silverlight中绘制基本图形。

IGraphBase和辅助绘图类放在一个文件中(Helper.cs),以下是代码。

    public class DrawColor
    {
        #region Member Variables
        private Byte _r, _g, _b, _a;
        #endregion Member Variables

        #region Properties
        public Byte R
        {
            set { this._r = value; }
            get { return this._r; }
        }
        public Byte G
        {
            set { this._g = value; }
            get { return this._g; }
        }
        public Byte B
        {
            set { this._b = value; }
            get { return this._b; }
        }
        public Byte A
        {
            set { this._a = value; }
            get { return this._a; }
        }
        #endregion Properties

        #region Public Methods
        public DrawColor(Byte a=255, Byte r =0,Byte g=0, Byte b=0)
        {
            _r = r;
            _g = g;
            _b = b;
            _a = a;
        }
        public DrawColor(Byte r = 0, Byte g = 0, Byte b = 0)
        {
            _a = 255;
            _g = g;
            _b = b;
            _r = r;
        }
        public UInt32 ToArgb()
        {
            return (((UInt32)_a) << 24) + (((UInt32)_r) << 16) + (((UInt32)_g) << 8) + ((UInt32)_b);
         }
        public static DrawColor FromArgb(int red, int green, int blue)
        {
            return new DrawColor((Byte)red, (Byte)green, (Byte)blue);        
        }
        public static DrawColor FromArgb(UInt32  cl)
        {
           return new DrawColor((Byte)(cl>>24),(Byte)(cl>>16),(Byte)(cl>>8),(Byte)(cl&0xff));
        }

        #endregion Public Methods
    }
    public class DrawColors
    {
        public static DrawColor Black = DrawColor.FromArgb(0xFF000000);
        public static DrawColor Blue = DrawColor.FromArgb(0xFF0000FF);
        public static DrawColor Brown = DrawColor.FromArgb(0xFFA52A2A);
        public static DrawColor Cyan = DrawColor.FromArgb(0xFF00FFFF);
        public static DrawColor DarkGray = DrawColor.FromArgb(0xFFA9A9A9);
        public static DrawColor Gray = DrawColor.FromArgb(0xFF808080);
        public static DrawColor Green = DrawColor.FromArgb(0xFF008000);
        public static DrawColor LightGray = DrawColor.FromArgb(0xFFD3D3D3);
        public static DrawColor Magenta = DrawColor.FromArgb(0xFFFF00FF);
        public static DrawColor Orange = DrawColor.FromArgb(0xFFFFA500);
        public static DrawColor Purple = DrawColor.FromArgb(0xFF800080);
        public static DrawColor Red = DrawColor.FromArgb(0xFFFF0000);
        public static DrawColor Transparent = DrawColor.FromArgb(0x00FFFFFF);
        public static DrawColor White = DrawColor.FromArgb(0xFFFFFFFF);
        public static DrawColor Yellow = DrawColor.FromArgb(0xFFFFFF00); 
     }

    public class LinePen
    {
        public enum StyleEnum
        {
            SOLID,
            DOT,
            DASH,
            DASHDOT,
            DASHDOTDOT,
            CUSTOM
        }

        #region Member Variables
        private Single[] _customDashGapArray = null;
        #endregion Member Variables
        
        #region Properties
        public StyleEnum Style { get; set; }
        public DrawColor Color { get; set; }
        public Single Width { get; set; }
        public Single[] CustomDashGapArray
        {
            get
            {
                return _customDashGapArray;
            }
            set 
            {
                if (value != null)
                {
                    _customDashGapArray = new Single[value.Length];
                    value.CopyTo(_customDashGapArray, 0);
                }
            }
        
        }
        #endregion Properties

        public LinePen(DrawColor color, Single width = 1.0f, StyleEnum style = LinePen.StyleEnum.SOLID, Single[] customDashGap = null)
        {
            Color = color;
            Width = width;
            Style = style;
            CustomDashGapArray = customDashGap;
        }

        public LinePen Clone()
        {
            return new LinePen(this.Color, this.Width, this.Style, this._customDashGapArray);
        }
    }
    public abstract class PaintBrush
    {

        #region Member Variables

        #endregion Member Variables

        #region Properties
        #endregion Properties

        public PaintBrush()
        {
        }
    }

    public class SolidPaintBrush: PaintBrush 
    {

        #region Properties
        public DrawColor Color { get; set; }
        #endregion Properties

        public SolidPaintBrush(DrawColor color)
        {
            Color = color;
        }
    }



    public class TextFont
    {
        public enum StyleEnum
        {
            REGULAR,
            BOLD,
            ITALIC
        }
        public enum AlignmentEnum
        {
            LEFT,
            RIGHT,
            CENTER,
            JUSTIFY
        }

        #region Member Variables
        private string _family;
        #endregion Member Variables

        #region Properties
        public bool Clip { get; set; }
        public bool Wrap { get; set; }
        public float Size {get; set; }
        public StyleEnum Style { get; set; }
        public AlignmentEnum Alignment { get; set; }
        public string Family
        {
            set { this._family = value; }
            get { return this._family; }
        }
        #endregion Properties

        #region Public Methods
        public TextFont(string family="宋体", float size=10.0f, TextFont.StyleEnum style = StyleEnum.REGULAR,
             TextFont.AlignmentEnum alignment = AlignmentEnum.LEFT, bool wrap= false, bool clip =false)
        {
            _family = family;
            Size = size;
            Style = style;
            Alignment = alignment;
            Wrap = wrap;
            Clip = clip;
         }
        public TextFont(float size)
        {
            _family = "宋体";
            Size = size;
            Style = StyleEnum.REGULAR;
            Alignment = AlignmentEnum.LEFT;
            Wrap = false;
            Clip = false;
         }
        #endregion Public Methods

    }
    public class Dot
    {
       public Int32 X=0,Y=0;
       public Dot(Int32 x, Int32 y)
       {
           this.X = x;
           this.Y = y;
       }
    }
    public class DotF
    {
       public Single X=0.0f,Y=0.0f;
       public DotF(Single x, Single y)
       {
           this.X = x;
           this.Y = y;
       }
    }

    public class Area
    {
        public Int32 X1,Y1,X2,Y2;
        public Area()
        {
            X1 = Y1 = X2 = Y2 = 0;
        }
        public Area(Int32 x1, Int32 y1, Int32 x2, Int32 y2)
        {
            this.X1 = x1;
            this.Y1 = y1;
            this.X2 = x2;
            this.Y2 = y2;
        }
        public Int32 Width
        {
            get { return X2 - X1; }
            set { X2 = X1 + value; }
        }
        public Int32 Height
        {
            get { return Y2 - Y1; }
            set { Y2 = Y1 + value; }
        }
        public void Reset()
        {
            int s;
            if (X2 < X1)
            {
                s = X2; X2 = X1; X1 = s;
            }
            if (Y2 < Y1)
            {
                s = Y2; Y2 = Y1; Y1 = s;
            }
        }
        public static Area FromRange(Int32 x, Int32  y, Int32 width, Int32 height)
        {
            return new Area(x, y, x + width, y + height);
        }
    }
    public class AreaF
    {
        public Single X1,Y1, X2,Y2;
        public AreaF()
        {
            X1 = Y1 = X2 = Y2 = 0.0f;
        }
        public AreaF(Single x1, Single y1, Single x2, Single y2)
        {
            this.X1 = x1;
            this.Y1 = y1;
            this.X2 = x2;
            this.Y2 = y2;
        }
        public Single Width
        {
            get { return X2 - X1; }
            set { X2 = X1 + value; }
        }
        public Single Height
        {
            get { return Y2 - Y1; }
            set { Y2 = Y1 + value; }        
        }
        public void Reset()
        {
            Single s;
            if (X2 < X1) 
            {
                s = X2; X2 = X1; X1 = s;
            }
            if (Y2 < Y1)
            {
                s = Y2; Y2 = Y1; Y1 = s;            
            }
        }
        public static AreaF FromRange(Single x, Single y, Single width, Single height)
        {
            return new AreaF(x, y, x + width, y + height);
        }
    }

    public enum ImageStretch
    {
        NONE,
        FILL,
        UNIFORM,
        UNIFORMTOFILL
    }
    
    public interface IGraphBase
    {
        void Clear(DrawColor cl);
        void SetClip(AreaF area );
        void ClearClip();
        void SetLinePen(LinePen pen);

        void DrawLine(LinePen pen, Int32 x1, Int32 y1, Int32 x2, Int32 y2);
        void DrawLine(LinePen pen, Single x1, Single y1, Single x2, Single y2);

        void StartPolyline(LinePen pen);
        void AddPolylinePoint(Single x, Single y);
        void AddPolylinePoint(Int32 x, Int32 y);
        void EndPolyline();

        void DrawRectangle(LinePen pen, PaintBrush brush, Area area);
        void DrawRectangle(LinePen pen, PaintBrush brush, AreaF area);
        void DrawRectangle(LinePen pen, PaintBrush brush, Int32 x1, Int32 y1, Int32 x2, Int32 y2);
        void DrawRectangle(LinePen pen, PaintBrush brush, Single x1, Single y1, Single x2, Single y2);

        void DrawPolygon(LinePen pen, PaintBrush brush, ICollection<Dot> edges);
        void DrawPolygon(LinePen pen, PaintBrush brush, ICollection<DotF> edges);

        void DrawCircle(LinePen pen, PaintBrush brush, Int32 x, Int32 y, Int32 radius);
        void DrawCircle(LinePen pen, PaintBrush brush, Single x, Single y, Single radius);

        void DrawEllipse(LinePen pen, PaintBrush brush, Area area);
        void DrawEllipse(LinePen pen, PaintBrush brush, AreaF area);
        void DrawEllipse(LinePen pen, PaintBrush brush, Int32 x1, Int32 y1, Int32 x2, Int32 y2);
        void DrawEllipse(LinePen pen, PaintBrush brush, Single x1, Single y1, Single x2, Single y2);

        void DrawString(Single x, Single y, string text, DrawColor fontcolor, float fontsize, string fontname);
        void DrawString(string text, TextFont font, PaintBrush brush, AreaF area);

        void DrawImage(Area area, string sourceUrl, ImageStretch st);
        void DrawImage(AreaF area, string sourceUrl, ImageStretch st);

    }
}
         SilverlightGraphics的源代码。

  public class SilverlightGraphics : IGraphBase
    {
        #region Consts & Enum
        #endregion Consts & Enum

        #region Member Variables
        private Canvas _slCanvas;
        private UInt32 _elementCount = 0;
        private LinePen _defaultPen = new LinePen(DrawColors.Black);
        private LinePen _polylinePen = null;
        private PointCollection _polylinePoints = null;

        private DoubleCollection _dotLineStrokeArray = new DoubleCollection();
        private DoubleCollection _dashLineStrokeArray = new DoubleCollection(); 
        private DoubleCollection _dashdotLineStrokeArray = new DoubleCollection();
        private DoubleCollection _dashdotdotLineStrokeArray = new DoubleCollection();
        private Brush _defaultTextBrush = new SolidColorBrush(Colors.Black);
        private System.Windows.FrameworkElement _lastAddedShape = null;
        #endregion Member Variables

        #region Properties
        public Canvas GraphObject
        {
            get { return _slCanvas; }
        }
        public System.Windows.FrameworkElement LastAddedShape
        {
            get { return _lastAddedShape; }
        }
        #endregion Properties

        #region Pulbic Methods
        public SilverlightGraphics(Canvas cs)
        {
            _slCanvas = cs;
            _dotLineStrokeArray.Add(1.0);        _dotLineStrokeArray.Add(1.0);
            _dashLineStrokeArray.Add(3.0);       _dashLineStrokeArray.Add(1.0);
            _dashdotLineStrokeArray.Add(3.0);   _dashdotLineStrokeArray.Add(1.0);     _dashdotLineStrokeArray.Add(1.0); _dashdotLineStrokeArray.Add(1.0);
            _dashdotdotLineStrokeArray.Add(3.0); _dashdotdotLineStrokeArray.Add(1.0); _dashdotdotLineStrokeArray.Add(1.0); _dashdotdotLineStrokeArray.Add(1.0); _dashdotdotLineStrokeArray.Add(1.0); _dashdotdotLineStrokeArray.Add(1.0);
        }
        public void SetLinePen(LinePen pen)
        {
            _defaultPen = pen.Clone();
        }

        public void Clear(DrawColor cl)
        {
            _slCanvas.Children.Clear();
            _slCanvas.Background = new SolidColorBrush(converttoColor(cl));
        }
        public void SetClip(AreaF area = null)
        {
            Rect rt = (area == null) ? new Rect(0, 0, _slCanvas.Width, _slCanvas.Height) : new Rect(area.X1, area.Y1, area.Width, area.Height);
            _slCanvas.Clip = new RectangleGeometry() { Rect = rt };

        }
       public void ClearClip()
        {
            _slCanvas.Clip = null;
        }

        public void DrawLine(LinePen pen, Int32 x1, Int32 y1, Int32 x2, Int32 y2)
        {
            DrawLine(pen, (Single)x1, (Single)y1, (Single)x2, (Single)y2);  
        }
        public void DrawLine(LinePen pen, Single x1, Single y1, Single x2, Single y2)
        {
            Line shp = new System.Windows.Shapes.Line();
            prepareLinePen(shp, (pen==null)?_defaultPen.Clone() :pen);
            shp.X1 = x1;
            shp.Y1 = y1;
            shp.X2 = x2;
            shp.Y2 = y2;

            addShape(shp, "Line");
        }

        public void StartPolyline(LinePen pen)
        { 
            if(_polylinePoints!=null) _polylinePoints.Clear();                           // need new ??????
            _polylinePen = (pen == null) ? _defaultPen.Clone() : pen;
        
        }
        public void AddPolylinePoint(Single x, Single y)
        {
            if (_polylinePoints == null)
            {
                _polylinePoints = new PointCollection();
            }
            _polylinePoints.Add(new Point(x, y));
        }
        public void AddPolylinePoint(Int32 x, Int32 y)
        {
            AddPolylinePoint((Single)x, (Single)y);
        }
        public void EndPolyline()
        {
            Polyline shp = new System.Windows.Shapes.Polyline();
            prepareLinePen(shp, _polylinePen);
            shp.Points = _polylinePoints;
            addShape(shp, "Pyln");

        }
        
        public void DrawRectangle(LinePen pen, PaintBrush brush, Area area)
        { 
            DrawRectangle(pen, brush, (Single)area.X1,(Single)area.Y1, (Single)area.Width, (Single)area.Height);       
        }
        public void DrawRectangle(LinePen pen, PaintBrush brush, AreaF area)
        {
            DrawRectangle(pen, brush, area.X1,area.Y1, area.Width, area.Height);
        }
        public void DrawRectangle(LinePen pen, PaintBrush brush, Int32 x, Int32 y, Int32 width, Int32 height)
        {
            DrawRectangle(pen, brush, (Single)x, (Single)y, (Single)width, (Single)height);
        }
        public void DrawRectangle(LinePen pen, PaintBrush brush, Single x, Single y, Single width, Single height)
        {
            Rectangle shp = new System.Windows.Shapes.Rectangle();
            prepareLinePen(shp, (pen == null) ? _defaultPen.Clone() : pen);
            prepareFillBrush(shp, brush);

            setRectValue(shp, x, y, width, height);
            addShape(shp, "Rect");

        }
        public void DrawPolygon(LinePen pen, PaintBrush brush, ICollection<Dot> edges)
        {
            Polygon tmpgon = new System.Windows.Shapes.Polygon();
            prepareLinePen(tmpgon, (pen == null) ? _defaultPen.Clone() : pen);
            prepareFillBrush(tmpgon, brush);
            PointCollection points = new PointCollection();
            foreach (Dot dt in edges)
            {
                points.Add(new Point(dt.X, dt.Y));
            }
            tmpgon.Points = points;
            addShape(tmpgon, "Pygn");
        }
        public void DrawPolygon(LinePen pen, PaintBrush brush, ICollection<DotF> edges)
        {
            Polygon tmpgon = new System.Windows.Shapes.Polygon();
            prepareLinePen(tmpgon, (pen == null) ? _defaultPen.Clone() : pen);
            prepareFillBrush(tmpgon, brush);
            PointCollection points = new PointCollection();
            foreach (DotF dot in edges)
            {
                points.Add(new Point(dot.X, dot.Y));
            }
            tmpgon.Points = points;

            addShape(tmpgon, "Pygn");

        }


        public void DrawCircle(LinePen pen, PaintBrush brush, Int32 x, Int32 y, Int32 radius)
        {
             DrawCircle(pen, brush, (Single)x, (Single)y, (Single)radius);
        }
        public void  DrawCircle(LinePen pen, PaintBrush brush, Single x, Single y, Single radius)
        {
            Ellipse shp = new System.Windows.Shapes.Ellipse();
            prepareLinePen(shp, (pen == null) ? _defaultPen.Clone() : pen);
            prepareFillBrush(shp, brush);
            setRectValue(shp, x - radius, y - radius, radius, radius);
            addShape(shp, "Crcl");

        }

        public void DrawEllipse(LinePen pen, PaintBrush brush, Area area)
        {
            DrawEllipse(pen, brush, (Single)area.X1, (Single)area.Y1, (Single)area.Width, (Single)area.Height);   
        }
        public void DrawEllipse(LinePen pen, PaintBrush brush, AreaF area)
        {
            DrawEllipse(pen, brush, area.X1, area.Y1, area.Width, area.Height);
        }
        public void DrawEllipse(LinePen pen, PaintBrush brush, Int32 x, Int32 y, Int32 width, Int32 height) 
        {
             DrawEllipse(pen, brush, (Single)x, (Single)y, (Single)width, (Single)height);
        }
        public void  DrawEllipse(LinePen pen, PaintBrush brush, Single x, Single y, Single width, Single height)
        {
            Ellipse shp = new System.Windows.Shapes.Ellipse();
            prepareLinePen(shp, (pen == null) ? _defaultPen.Clone() : pen);
            prepareFillBrush(shp, brush);
            setRectValue(shp, x, y, width, height);

            addShape(shp, "Elps");
        }

        public void DrawString(string text, TextFont font, PaintBrush  brush, AreaF area)
       {
           System.Windows.Controls.TextBlock shp = new TextBlock();

           switch (font.Alignment)
           { 
               case TextFont.AlignmentEnum.LEFT:
                   shp.TextAlignment = TextAlignment.Left;
                   break;
               case TextFont.AlignmentEnum.RIGHT:
                   shp.TextAlignment = TextAlignment.Right;
                   break;
               case TextFont.AlignmentEnum.CENTER:
                   shp.TextAlignment = TextAlignment.Center;
                   break;
               case TextFont.AlignmentEnum.JUSTIFY:
                   shp.TextAlignment = TextAlignment.Justify;
                   break;
           }
           switch (font.Style)
           {
               case TextFont.StyleEnum.REGULAR:
                   break;
               case TextFont.StyleEnum.BOLD:
                    shp.FontWeight = FontWeights.Bold;
                   break;
               case TextFont.StyleEnum.ITALIC:
                   shp.FontStyle = FontStyles.Italic;
                   break;
           }
           if (font.Clip)
           {
               shp.Clip = new RectangleGeometry() { Rect = new Rect(0, 0, area.Width, area.Height) };
           }
           shp.TextWrapping = (font.Wrap) ? TextWrapping.Wrap : TextWrapping.NoWrap;
           shp.Foreground = (brush == null) ? _defaultTextBrush : converttoBrush(brush);
           shp.Text = text;
           setRectValue(shp, area.X1, area.Y1, area.Width, area.Height);
           shp.FontSize = font.Size;
           shp.FontFamily = new FontFamily(font.Family);

           addShape(shp, "Text");
         }
        public void DrawString(Single x, Single y, string text, DrawColor fontcolor , float fontsize=10.0f, string fontname = "宋体")
        {
            AreaF area = new AreaF(){ X1 = x,Y1= y,X2=x+10, Y2= y+10};
            TextFont font = new TextFont(fontname,fontsize);
            SolidPaintBrush  brush = new SolidPaintBrush (fontcolor);
            DrawString(text, font, brush, area);
        }

        public void DrawImage(Area area, string sourceUrl, ImageStretch st)
        {
            DrawImage(area.X1, area.Y1, area.Width, area.Height, sourceUrl, st);
        }
        public void DrawImage(AreaF area, string sourceUrl, ImageStretch st)
        {
            DrawImage(area.X1, area.Y1, area.Width, area.Height, sourceUrl, st);
        }
        public void DrawImage(Single x, Single y, Single width, Single height, string sourceUrl, ImageStretch st)
        {
            Image shp = new System.Windows.Controls.Image();
            setRectValue(shp, x, y, width , height);
            shp.Stretch = converttoStretch(st);
            shp.Source = new BitmapImage(new Uri(sourceUrl, UriKind.RelativeOrAbsolute));
            addShape(shp, "Imag");        
        }

 
        #endregion Pulbic Methods

        #region Private Methods
        private Color converttoColor(DrawColor cl)
        {
            Color clr= new Color();
            clr.A = cl.A;
            clr.B = cl.B;
            clr.G = cl.G;
            clr.R = cl.R;
            return clr;
        }
        private Brush converttoBrush(PaintBrush pbr)
        { 
             if (pbr is SolidPaintBrush)
            {
                return new SolidColorBrush(converttoColor((((SolidPaintBrush)pbr).Color)));
            
            }
             return null;
        }
        private Stretch converttoStretch(ImageStretch st)
        { 
            switch(st)
            {
                case ImageStretch.NONE:
                    return Stretch.None;
                case ImageStretch.FILL:
                    return Stretch.Fill;
                case ImageStretch.UNIFORM:
                    return Stretch.Uniform;
                case ImageStretch.UNIFORMTOFILL:
                   return Stretch.UniformToFill;
            }
            return Stretch.None;
        
        }
        private void prepareLinePen(System.Windows.Shapes.Shape shp, LinePen pen)
        {
            switch (pen.Style)
            {
                case LinePen.StyleEnum.SOLID:
                    shp.Stroke = new SolidColorBrush(converttoColor(pen.Color));
                    break;
                case LinePen.StyleEnum.DOT:
                    shp.Stroke = new SolidColorBrush(converttoColor(pen.Color));
                    shp.StrokeDashArray = _dotLineStrokeArray;
                    break;
                case LinePen.StyleEnum.DASH:
                    shp.Stroke = new SolidColorBrush(converttoColor(pen.Color));
                    shp.StrokeDashArray = _dashLineStrokeArray;
                    break;
                case LinePen.StyleEnum.DASHDOT:
                    shp.Stroke = new SolidColorBrush(converttoColor(pen.Color));
                    shp.StrokeDashArray = _dashdotdotLineStrokeArray;
                    break;
                case LinePen.StyleEnum.DASHDOTDOT:
                    shp.Stroke = new SolidColorBrush(converttoColor(pen.Color));
                    shp.StrokeDashArray = _dashdotdotLineStrokeArray;
                    break;
                case LinePen.StyleEnum.CUSTOM:
                    shp.Stroke = new SolidColorBrush(converttoColor(pen.Color));
                    Single[] dashgapArray = pen.CustomDashGapArray;
                    DoubleCollection customLineStrokeArray = new DoubleCollection();
                    foreach (Single i in dashgapArray)
                    {
                        customLineStrokeArray.Add(i);
                    }
                    shp.StrokeDashArray = customLineStrokeArray;
                    break;
            }
            shp.StrokeThickness = pen.Width;

        }
        private void prepareFillBrush(System.Windows.Shapes.Shape shp, PaintBrush brh)
        {
            if (brh != null)
            {
                shp.Fill = converttoBrush(brh);
            }
          
        }
        private void setRectValue(System.Windows.FrameworkElement shp, double x, double y, double width, double height)
        {
            shp.Width = width;
            shp.Height = height;
            shp.SetValue(Canvas.LeftProperty, x);
            shp.SetValue(Canvas.TopProperty, y);
        }
        private void addShape(System.Windows.FrameworkElement tmpshape, string namePrefix)
        {
            tmpshape.Name = namePrefix + _elementCount.ToString();
            _slCanvas.Children.Add(tmpshape);
            _elementCount++;
            _lastAddedShape = tmpshape;
        }
        #endregion Private Methods
    }

        WinFormGraphics的源代码。

  public class WinFormGraphics:IGraphBase
    {
        #region Consts & Enum
        #endregion Consts & Enum

        #region Member Variables
        private Graphics _canvas;
        private UInt32 _elementCount = 0;
        private Pen _defaultPen = new Pen(Color.Black);
        private Pen _polylinePen = null;
        private List<PointF> _polylinePoints = null;


        //private Brush _defaultTextBrush = new SolidColorBrush(Colors.Black);
        //private System.Windows.FrameworkElement _lastAddedShape = null;
        #endregion Member Variables

        #region Properties
        public Graphics GraphObject
        {
            get { return _canvas; }
        }
        //public System.Windows.FrameworkElement LastAddedShape
        //{
        //    get { return _lastAddedShape; }
        //}
        #endregion Properties

        #region Pulbic Methods
        public WinFormGraphics(Graphics cs)
        {
            _canvas = cs;
        }
        public void SetLinePen(LinePen pen)
        {
            _defaultPen = (pen==null)?null: converttoPen(pen);
        }

       public void Clear(DrawColor cl)
        {
            _canvas.Clear(converttoColor(cl));
        }
       public void SetClip(AreaF area)
        {
            if(area != null)
            {
               _canvas.SetClip(new RectangleF(area.X1, area.Y1, area.Width, area.Height));
            }

        }
        public void ClearClip()
        {
            _canvas.ResetClip();
        }

        public void DrawLine(LinePen pen, Int32 x1, Int32 y1, Int32 x2, Int32 y2)
        {
            DrawLine(pen, (Single)x1, (Single)y1, (Single)x2, (Single)y2);  
        }
        public void DrawLine(LinePen pen, Single x1, Single y1, Single x2, Single y2)
        {
            Pen pp = converttoPen(pen);
            _canvas.DrawLine(pp, x1, y1, x2, y2);
            _elementCount++;
        }

        public void StartPolyline(LinePen pen)
        { 
            if(_polylinePoints!=null) _polylinePoints.Clear();                           // need new ??????
            _polylinePen = (pen == null) ? _defaultPen : converttoPen(pen);
        
        }
        public void AddPolylinePoint(Single x, Single y)
        {
            if (_polylinePoints == null)
            {
                _polylinePoints = new List<PointF>();
            }
            _polylinePoints.Add(new PointF(x, y));
        }
        public void AddPolylinePoint(Int32 x, Int32 y)
        {
            AddPolylinePoint((Single)x, (Single)y);
        }
        public void EndPolyline()
        {
            _canvas.DrawLines(_polylinePen, _polylinePoints.ToArray());
            _elementCount++;
        }

        public void DrawRectangle(LinePen pen, PaintBrush brush, Area area)
        { 
            DrawRectangle(pen, brush, (Single)area.X1,(Single)area.Y1, (Single)area.Width, (Single)area.Height);       
        }
        public void DrawRectangle(LinePen pen, PaintBrush brush, AreaF area)
        {
            DrawRectangle(pen, brush, area.X1,area.Y1, area.Width, area.Height);
        }
        public void DrawRectangle(LinePen pen, PaintBrush brush, Int32 x, Int32 y, Int32 width, Int32 height)
        {
            if (brush == null)
            {
                Pen pp = (pen == null) ? _defaultPen : converttoPen(pen);
                _canvas.DrawRectangle(pp, x, y, width, height);
            }
            else
            {
                Brush bb = converttoBrush(brush);
                _canvas.FillRectangle(bb, x, y, width, height);
            }
            _elementCount++;

        }
        public void DrawRectangle(LinePen pen, PaintBrush brush, Single x, Single y, Single width, Single height)
        {
            if (brush == null)
            {
                Pen pp = (pen == null) ? _defaultPen : converttoPen(pen);
                _canvas.DrawRectangle(pp, x, y, width, height);
            }
            else
            {
                Brush bb = converttoBrush(brush);
                _canvas.FillRectangle(bb, x, y, width, height);
            }
            _elementCount++;

        }
        public void DrawPolygon(LinePen pen, PaintBrush brush, ICollection<Dot> edges)
        {
            Point[] points = new Point[edges.Count];
            int i=0;
            foreach(Dot dot in edges)
            {
                points[i].X = dot.X;
                points[i].Y = dot.Y;
                i++;
            }

            if (brush == null)
            {
                Pen pp = (pen == null) ? _defaultPen : converttoPen(pen);
                _canvas.DrawPolygon(pp, points);
            }
            else
            {
                Brush bb = converttoBrush(brush);
                _canvas.FillPolygon (bb, points);
            }
            _elementCount++;
        }
        public void DrawPolygon(LinePen pen, PaintBrush brush, ICollection<DotF> edges)
        {
            PointF[] points = new PointF[edges.Count];
            int i = 0;
            foreach (DotF dot in edges)
            {
                points[i].X = dot.X;
                points[i].Y = dot.Y;
                i++;
            }
            if (brush == null)
            {
                Pen pp = (pen == null) ? _defaultPen : converttoPen(pen);
                _canvas.DrawPolygon(pp, points);
            }
            else
            {
                Brush bb = converttoBrush(brush);
                _canvas.FillPolygon(bb, points);
            }
            _elementCount++;
        }

        public void DrawCircle(LinePen pen, PaintBrush brush, Int32 x, Int32 y, Int32 radius)
        {
             DrawCircle(pen, brush, (Single)x, (Single)y, (Single)radius);
        }
        public void  DrawCircle(LinePen pen, PaintBrush brush, Single x, Single y, Single radius)
        {
            DrawEllipse(pen, brush, x - radius, y - radius,  radius, radius);
        }

        public void DrawEllipse(LinePen pen, PaintBrush brush, Area area)
        {
            DrawEllipse(pen, brush, (Single)area.X1, (Single)area.Y1, (Single)area.Width, (Single)area.Height);   
        }
        public void DrawEllipse(LinePen pen, PaintBrush brush, AreaF area)
        {
            DrawEllipse(pen, brush, area.X1, area.Y1, area.Width, area.Height);
        }
        public void DrawEllipse(LinePen pen, PaintBrush brush, Int32 x, Int32 y, Int32 width, Int32 height) 
        {
            if (brush == null)
            {
                Pen pp = (pen == null) ? _defaultPen : converttoPen(pen);
                _canvas.DrawEllipse(pp, x, y, width, height);
            }
            else
            {
                Brush bb = converttoBrush(brush);
                _canvas.FillEllipse(bb, x, y, width, height);
            }
            _elementCount++;
        }
        public void  DrawEllipse(LinePen pen, PaintBrush brush, Single x, Single y, Single width, Single height)
        {
            if (brush == null)
            {
                Pen pp = (pen == null) ? _defaultPen : converttoPen(pen);
                _canvas.DrawEllipse(pp, x, y, width, height);
            }
            else
            {
                Brush bb = converttoBrush(brush);
                _canvas.FillEllipse(bb, x, y, width, height);
            }
            _elementCount++;
        }

        public void DrawString(string text, TextFont font, PaintBrush  brush, AreaF area)
       {
           StringFormat ft = new StringFormat();
           if (!font.Wrap) ft.FormatFlags = StringFormatFlags.NoWrap;
           if (!font.Clip) ft.FormatFlags = ft.FormatFlags|StringFormatFlags.NoClip ; 
           switch (font.Alignment)
           { 
               case TextFont.AlignmentEnum.LEFT:
                   ft.Alignment = StringAlignment.Near;
                   break;
               case TextFont.AlignmentEnum.RIGHT:
                   ft.Alignment = StringAlignment.Far;
                   break;
               case TextFont.AlignmentEnum.CENTER:
                   ft.Alignment = StringAlignment.Center;
                   break;
               case TextFont.AlignmentEnum.JUSTIFY:
                   ft.Alignment = StringAlignment.Near;
                   break;
           }
           FontStyle ftstyle = FontStyle.Regular;
           switch (font.Style)
           {
               case TextFont.StyleEnum.REGULAR:
                   break;
               case TextFont.StyleEnum.BOLD:
                   ftstyle = FontStyle.Bold;
                   break;
               case TextFont.StyleEnum.ITALIC:
                   ftstyle = FontStyle.Italic;
                   break;
           }

           Font fot = new Font(new FontFamily(font.Family), font.Size, ftstyle);
           RectangleF rt = new RectangleF(area.X1, area.Y1, area.Width, area.Height);
           if (!font.Clip)  //it seems that StringFormatFlags.NoClip does not work! here donot use that flag. 
           {
               SizeF stringSize = new SizeF();
               if (font.Wrap)
               {
                   stringSize = _canvas.MeasureString(text, fot, (int)area.Width, ft);
               }
               else
               {
                   stringSize = _canvas.MeasureString(text, fot, new PointF(area.X1, area.Y1), ft);
               }

               rt.Width = (area.Width > stringSize.Width) ? area.Width : stringSize.Width;
               rt.Height= (area.Height>stringSize.Height)?area.Height:stringSize.Height;
           }
           _canvas.DrawString(text, fot, converttoBrush(brush), rt, ft);
            _elementCount++;

         }
        public void DrawString(Single x, Single y, string text, DrawColor fontcolor , float fontsize=10.0f, string fontname = "宋体")
        {
            Font fot = new Font(new FontFamily(fontname), fontsize, FontStyle.Regular);
            _canvas.DrawString(text, fot, new SolidBrush(converttoColor(fontcolor)), new PointF(x,y));
            _elementCount++;
        }

        public void DrawImage(Area area, string sourceUrl, ImageStretch st)
        {
            DrawImage(area.X1, area.Y1, area.Width, area.Height, sourceUrl, st);
        }
        public void DrawImage(AreaF area, string sourceUrl, ImageStretch st)
        {
            DrawImage(area.X1, area.Y1, area.Width, area.Height, sourceUrl, st);
        }
        public void DrawImage(Single x, Single y, Single width, Single height, string sourceUrl, ImageStretch st)
        {
            Image newImage = Image.FromFile(sourceUrl);
            switch (st)
            {
                case ImageStretch.UNIFORMTOFILL:
                case ImageStretch.NONE:
                    _canvas.DrawImage(newImage,x,y);
                    break;
                case ImageStretch.FILL:            //to be stretched to the size of the holder
                    _canvas.DrawImage(newImage, new RectangleF(x, y, width, height));
                    break;
                case ImageStretch.UNIFORM:       //to be stretched according to the proportion of the image
                    if (height / newImage.Size.Height > width / newImage.Size.Width)
                    {
                        _canvas.DrawImage(newImage, new RectangleF(x, y, width, newImage.Size.Height * width / newImage.Size.Width));
                    }
                    else
                    {
                        _canvas.DrawImage(newImage, new RectangleF(x, y,  newImage.Size.Width * height / newImage.Size.Height, height));                    
                    }

                    break;
            }
            _elementCount++;
      
        }

 
        #endregion Pulbic Methods

        #region Private Methods
        private Color converttoColor(DrawColor cl)
        {
            return Color.FromArgb(cl.A, cl.R, cl.G, cl.B);
        }
        private Pen converttoPen(LinePen pen)
        {
            Pen pp = new Pen(converttoColor(pen.Color), pen.Width);
            switch (pen.Style)
            {
                case LinePen.StyleEnum.SOLID:
                    pp.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
                    break;
                case LinePen.StyleEnum.DOT:
                    pp.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                    break;
                case LinePen.StyleEnum.DASH:
                    pp.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                    break;
                case LinePen.StyleEnum.DASHDOT:
                    pp.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot;
                    break;
                case LinePen.StyleEnum.DASHDOTDOT:
                    pp.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDotDot;
                    break;
                case LinePen.StyleEnum.CUSTOM:
                    pp.DashPattern = pen.CustomDashGapArray;
                    break;
            }
            return pp;
        }
        private Brush converttoBrush(PaintBrush pbr)
        { 
             if (pbr is SolidPaintBrush)
            {
                return new SolidBrush(converttoColor((((SolidPaintBrush)pbr).Color)));
            
            }
             return null;
        }
 
        #endregion Private Methods
    }



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值