图形的绘制有多种,本文采用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);
}
}