WPF 中Canvas图形绘制之DrawingContext绘图(二)

图形的绘制有多种,本文采用DrawingContext。

1、定义接口

public interface iDrawingVisualSignal
{
	/// 
	/// 基点
	/// 
	Point ptBase { get; set; }
}

2、定义图元类,实现图元内部图形的绘制

public class DV_TrackLine : FrameworkElement, iDrawingVisualSignal
{
    #region 接口属性
    public Point ptBase { get; set; }
    #endregion
    private double iLength = 40;
    private double iScale = 1;
    public bool bSelected = false;
    public bool bHit = false;
    int iMarginX = 10;  
    TrackLine _trackLine = new TrackLine();
    public DV_TrackLine(TrackLine signalLamp)
    {
        _trackLine = signalLamp;
        iLength = Convert.ToInt32(ConfigurationManager.AppSettings["TrackLineLength"]);
        iScale = Convert.ToInt32(ConfigurationManager.AppSettings["TrackLineScale"]);
    }
    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext); 

        Pen pen1 = new Pen(bSelected || bHit ? Brushes.White : Brushes.Red, bSelected || bHit ? 4f : 1f);
        pen1.Freeze();  //冻结画笔,这样能加快绘图速度

		// 绘制直线
        drawingContext.DrawLine(pen1, new Point(0, 0), ptConnect);
		// 绘制文本
        FormattedText text = new FormattedText("S1", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Tahoma"), 16 * 1, Brushes.White, 1);
        double de = text.Width / 2.0;
        double dew = text.Height + 4;

        Point ptT = new Point(ptConnect.X/2 - de, -dew);
        drawingContext.DrawText(text, ptT);

    }
}

图元类的图形绘制,在OnRender重载函数中实现,绘制的坐标系与canvas相同。接口中定义的ptBase,主要是用于确定图元对象在canvas画布中的位置。

3、图元类的实例化

定义了一个单体类,用于存放所有的图元,下面的代码作为示例,只是创建一个图元。

public class TrainSingalService : SingletonNetcore
{
	public TrainSingalService()
	{
		lstSignal.Clear();
	}
	public void Regen(Canvas canvas, double dpi)
	{
		var t12 = new DV_TrackLine(new TrackLine());
		t12.ptBase = new Point(100, 100);
		canvas.Children.Add(t12);

		Canvas.SetTop(t12, t12.ptBase.X);
		Canvas.SetLeft(t12, t12.ptBase.Y);
	}
}

创建DV_TrackLine类实例后,将其在Canvas中的定位坐标保存在ptBase中,并通过SetTop和SetLeft函数定位。

在MainWindow类中,调用单体类,传入canvas对象,实现图元的绘制。

 private void RegenGeometry()
        {
            canvas.Reset();
            double dpi = VisualTreeHelper.GetDpi(this).PixelsPerDip;
            TrainSingalService.Instance.Regen(canvas, dpi);
        }

4、图元类的复位

图元移动后,其在canvas中的位置也需要复位,在PanAndZoomCanvas类的Reset()函数改造如下

public void Reset()
{
    Zoomfactor = 1.1f;

    foreach (UIElement child in this.Children)
    {
        // 恢复缩放比例
        child.RenderTransform = Transform.Identity;
        // 恢复初始位置
        iDrawingVisualSignal iDrawing = child as iDrawingVisualSignal;
        Canvas.SetTop(child, iDrawing.ptBase.X);
        Canvas.SetLeft(child, iDrawing.ptBase.Y);
    }
}

你可能感兴趣的:(#,WPF绘图,wpf,c#)