• WPF程序使用矢量图资源绘制井口装置图


    一、简介

    石油行业软件开发中需要使用大量的不同类型的图件,由于具体项目需求多变,很难找到完全符合项目需要的图件库。在之前的项目中曾经使用GDI技术开发了一套基础绘图框架,实现代码量很大,绘制效果比较简陋。而WPF技术支持使用矢量图资源绘制,我们可以通过使用专业的矢量图工具软件,设计精美的矢量图资源,使用这些资源来绘制图形。实现简单,代码量小,可灵活组合,生成不同类型的图元库。

    二、矢量图元资源制作

    矢量图元工具种类繁多,我这里使用CorelDRAW X8软件。

    打开软件,新建一个图片文件。

    添加矩形

    使用交互式填充工具,填充渐变颜色

    点击右上方“重复和镜像”,实现仿立体的渐变效果。

    使用类似的方式,组合设计井口装置不同类型图元

     

     

     

    套管头

     

    四通

     

    单闸板分割器

    双闸板分割器

     

    所有的图元设计完成后,为了能在WPF中使用还需要转换成微软提供的xaml矢量图格式。

    把图元导出成“.emf”格式文件。

    使用微软的Microsoft Expression Design工具,导入EMF文件,转换导出成.xaml格式的资源文件。

     

     

    也可以使用其它第三方软件进行转换,网上也有免费在线转换URL,可在线转换。

    三、WPF绘图库设计

    Win32、WinFormsGDI是当今Window桌面应用程序的主流图形库,GDI图形系统已经形成了很多年。它提供了2D图形和文本功能,以及受限的图像处理功能。在WPF中,引入一种新的图形合成引擎。可以提供更高丰富的图形显式合成,而且不会有任何的窗口闪烁问题。这种新的显式提交引擎与传统的Win32、Windows Forms相比主要有两个优点: 1、所有的每个窗口元素都可以任意的交替重叠。 2、所有的合成操作都是Direct3D中的离屏表面(Off-screen Surface)中实现的。

    (一) 画布面板类(DrawingCanvas):支持从Canvas对象继承,内部有VisualCollection集合用来记录画布面板里包含的图元对象。

    功能包括:图元对象组织、图元添加和删除、图元对象排序(图层,上下排序)、画布缩放、鼠标事件代理(图元选择、图元右键菜单等)、绘图对象属性设置(字体、画笔、大小、位置等相关数据),图元对象绘图工具集合、命令模式封装实现(图元编辑的撤销操作)等。

    public class DrawingCanvas : Canvas
    
    {
    
    #region Class Members
    
    // Collection contains instances of GraphicsBase-derived classes.
    
    private VisualCollection graphicsList;
    
    // Dependency properties
    
    public static readonly DependencyProperty ToolProperty;
    
    public static readonly DependencyProperty ActualScaleProperty;
    
    public static readonly DependencyProperty IsDirtyProperty;
    
    public static readonly DependencyProperty LineWidthProperty;
    
    public static readonly DependencyProperty ObjectColorProperty;
    
    public static readonly DependencyProperty TextFontFamilyNameProperty;
    
    public static readonly DependencyProperty TextFontStyleProperty;
    
    public static readonly DependencyProperty TextFontWeightProperty;
    
    public static readonly DependencyProperty TextFontStretchProperty;
    
    public static readonly DependencyProperty TextFontSizeProperty;
    
    public static readonly DependencyProperty CanUndoProperty;
    
    public static readonly DependencyProperty CanRedoProperty;
    
    public static readonly DependencyProperty CanSelectAllProperty;
    
    public static readonly DependencyProperty CanUnselectAllProperty;
    
    public static readonly DependencyProperty CanDeleteProperty;
    
    public static readonly DependencyProperty CanDeleteAllProperty;
    
    public static readonly DependencyProperty CanMoveToFrontProperty;
    
    public static readonly DependencyProperty CanMoveToBackProperty;
    
    public static readonly DependencyProperty CanSetPropertiesProperty;
    
    public static readonly RoutedEvent IsDirtyChangedEvent;
    
    private Tool[] tools; // Array of tools
    
    ToolText toolText;
    
    ToolPointer toolPointer;
    
    private ContextMenu contextMenu;
    
    private UndoManager undoManager;
    
    public DrawingCanvas()
    
    : base()
    
    {
    
    graphicsList = new VisualCollection(this);
    
    CreateContextMenu();
    
    this.FocusVisualStyle = null;
    
    this.Loaded += new RoutedEventHandler(DrawingCanvas_Loaded);
    
    this.MouseDown += new MouseButtonEventHandler(DrawingCanvas_MouseDown);
    
    this.MouseMove += new MouseEventHandler(DrawingCanvas_MouseMove);
    
    this.MouseUp += new MouseButtonEventHandler(DrawingCanvas_MouseUp);
    
    this.KeyDown += new KeyEventHandler(DrawingCanvas_KeyDown);
    
    this.LostMouseCapture += new MouseEventHandler(DrawingCanvas_LostMouseCapture);}

    (一) 基本图元对象GraphicsBase:这是个抽象类,从DrawingVisual对象继承。DrawingVisual对象是WPF绘图系统提供的轻量级高性能的绘图类。

    Visual 类的层次结构如下:

    DrawingVisual 继承自Visual,是一个用于呈现形状、图像或文本的轻量绘图类。 此类之所以被视为轻量,是因为它不提供布局或事件处理功能,从而能够改善运行时性能。 因此,绘图最适于背景和剪贴画。

    图元对象中定义最重要的虚方法使用DrawingContext对象绘制图元,我们扩展图元绘制的逻辑是在这里来实现的

    public abstract class GraphicsBase : DrawingVisual
    
    public virtual void Draw(DrawingContext drawingContext)
    
    {
    
    }
    
    //接下来,定义不同类型的图元类:
    
    //直线
    
    public class GraphicsLine : GraphicsBase
    
    //圆形
    
    public class GraphicsEllipse : GraphicsRectangleBase
    
    //矩形抽象类
    
    public abstract class GraphicsRectangleBase : GraphicsBase
    
    //多边形
    
    public class GraphicsPolyLine : GraphicsBase
    
    //不同的图元通过重写Draw虚方法来,实现不同的绘制方法
    
    //直线绘制:
    
    public override void Draw(DrawingContext drawingContext)
    
    {
    
    if ( drawingContext == null )
    
    {
    
    throw new ArgumentNullException("drawingContext");
    
    }
    
    drawingContext.DrawLine(
    
    new Pen(new SolidColorBrush(ObjectColor), ActualLineWidth),
    
    lineStart,
    
    lineEnd);
    
    base.Draw(drawingContext);
    
    }
    
    //圆形绘制:
    
    public override void Draw(DrawingContext drawingContext)
    
    {
    
    if ( drawingContext == null )
    
    {
    
    throw new ArgumentNullException("drawingContext");
    
    }
    
    Rect r = Rectangle;
    
    Point center = new Point(
    
    (r.Left + r.Right) / 2.0,
    
    (r.Top + r.Bottom) / 2.0);
    
    double radiusX = (r.Right - r.Left) / 2.0;
    
    double radiusY = (r.Bottom - r.Top) / 2.0;
    
    drawingContext.DrawEllipse(
    
    null,
    
    new Pen(new SolidColorBrush(ObjectColor), ActualLineWidth),
    
    center,
    
    radiusX,
    
    radiusY);
    
    }

    (三) 基于矢量图资源的井口装置图图元绘制

    我们可扩展矩形绘图图元,使其支持矢量图绘制功能,来实现绘制井口装置图。

    具体做法是,不绘制矩形边线,使用矢量图资源当作背景,来绘制矩形图元。

    1) 把xaml格式的矢量图图元文件以“content”的形式引入项目中

     

     

    1) 把文件添加到项目App.xaml文件,添加到Application Resources字典里

    <Application.Resources>
    
    <ResourceDictionary>
    
    <ResourceDictionary.MergedDictionaries>
    
    <ResourceDictionary Source="pack://siteoforigin:,,,/../3.xaml" />
    
    <ResourceDictionary Source="pack://siteoforigin:,,,/../st.xaml" />
    
    <ResourceDictionary Source="pack://siteoforigin:,,,/../hx.xaml" />
    
    <ResourceDictionary Source="pack://siteoforigin:,,,/../dzb.xaml" />
    
    <ResourceDictionary Source="pack://siteoforigin:,,,/../szb.xaml" />
    
    <ResourceDictionary Source="pack://siteoforigin:,,,/../jk.xaml" />
    
    <ResourceDictionary Source="pack://siteoforigin:,,,/../tgt.xaml" />
    
    </ResourceDictionary.MergedDictionaries>
    
    </ResourceDictionary>
    
    </Application.Resources>

    2) 重新Draw方法,使用矢量图资源绘制图元

    public override void Draw(DrawingContext drawingContext)
    
    {
    
    if (drawingContext == null)
    
    {
    
    throw new ArgumentNullException("drawingContext");
    
    }
    
    DrawingBrush background = null;
    
    //获取井口矢量图图元
    
    background = Application.Current.FindResource("jk") as DrawingBrush;
    
    //绘制图元
    
    drawingContext.DrawRectangle(
    
    background,
    
    new Pen(Brushes.Transparent, 0),
    
    Rectangle);
    
    //drawingContext.DrawText()
    
    base.Draw(drawingContext);
    
    }

    四、示例介绍

    我简单实现了个示例来展示井口装置图绘制

     

     

     

     

    单击上面井口装置图标,添加所对应的装置到当前画板。

    可选中图标,可缩放调节宽高,拖拽移动等。

    调整宽度组合图元,来实现井口装置图,还可以在任意位置添加文本,线端等其它图元。

    可保存绘图到xml文件中。

     

     

    转自:https://zhuanlan.zhihu.com/p/37167062

     

  • 相关阅读:
    Mac environment setting
    详解nginx.conf文件配置项(包括负载均衡)
    检查windows端口被占用
    linux下的环境变量
    利用MVC思想和php语言写网站的心得
    React学习:列表&&Key
    React学习:条件渲染
    事件处理
    state&生命周期
    react学习:组件&props
  • 原文地址:https://www.cnblogs.com/nepulgh/p/13129276.html
Copyright © 2020-2023  润新知