65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 WPF 的图形绘制工具

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.33/5 (5投票s)

2011年6月20日

GPL3

2分钟阅读

viewsIcon

44488

downloadIcon

3081

WPF 图形绘制工具

引言

本文介绍 WPF 及其绘图工具。

代码结构与我在 CodeProject 上的另一篇文章类似,链接如下:

WinFormVersions of GraphicsDrawingTool.aspx

背景

要理解本文,您需要了解一些 WPF 技术。例如 DrawingContext、FrameworkElement 类及其用法,以及如何编写 XAML GUI 界面。

使用代码

该项目首先创建一个工具箱,如下所示:

wpf2.jpg

然后用户可以在屏幕上绘制他们选择的形状,如下所示:

wpf1.jpg

然后可以将绘图导出为 XML 文件或 JPG 文件。

<?xml version="1.0" encoding="utf-8"?>
<ShapeList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ShapeList>
    <LeShape xsi:type="LeRectangle">
      <ShowBorder>true</ShowBorder>
      <LeBorderColor>
        <A>255</A>
        <R>0</R>
        <G>0</G>
        <B>0</B>
      </LeBorderColor>
      <BorderWidth>1</BorderWidth>
      <Rect>
        <X>300</X>
        <Y>157</Y>
        <Width>79</Width>
        <Height>65</Height>
      </Rect>
      <LeFromColor>
        <A>30</A>
        <R>255</R>
        <G>0</G>
        <B>0</B>
      </LeFromColor>
      <LeToColor>
        <A>30</A>
        <R>255</R>
        <G>255</G>
        <B>255</B>
      </LeToColor>
      <LightAngle>225</LightAngle>
      <Fill>true</Fill>
    </LeShape>
    <LeShape xsi:type="RoundRectShape">
      <ShowBorder>true</ShowBorder>
      <LeBorderColor>
        <A>255</A>
        <R>0</R>
        <G>0</G>
        <B>0</B>
      </LeBorderColor>
      <BorderWidth>1</BorderWidth>
      <Rect>
        <X>174</X>
        <Y>230</Y>
        <Width>84</Width>
        <Height>74</Height>
      </Rect>
      <LeFromColor>
        <A>255</A>
        <R>0</R>
        <G>0</G>
        <B>0</B>
      </LeFromColor>
      <LeToColor>
        <A>255</A>
        <R>127</R>
        <G>255</G>
        <B>212</B>
      </LeToColor>
      <LightAngle>225</LightAngle>
      <Fill>true</Fill>
      <Radius>10</Radius>
    </LeShape>
    <LeShape xsi:type="ZoneShape">
      <ShowBorder>true</ShowBorder>
      <LeBorderColor>
        <A>255</A>
        <R>0</R>
        <G>0</G>
        <B>0</B>
      </LeBorderColor>
      <BorderWidth>1</BorderWidth>
      <Rect>
        <X>132</X>
        <Y>97</Y>
        <Width>90</Width>
        <Height>84</Height>
      </Rect>
      <LeFromColor>
        <A>30</A>
        <R>255</R>
        <G>0</G>
        <B>0</B>
      </LeFromColor>
      <LeToColor>
        <A>30</A>
        <R>255</R>
        <G>255</G>
        <B>255</B>
      </LeToColor>
      <LightAngle>225</LightAngle>
      <Fill>true</Fill>
      <TextField>
        <ShowBorder>true</ShowBorder>
        <LeBorderColor>
          <A>255</A>
          <R>0</R>
          <G>0</G>
          <B>0</B>
        </LeBorderColor>
        <BorderWidth>1</BorderWidth>
        <Rect>
          <X>237</X>
          <Y>112</Y>
          <Width>58</Width>
          <Height>22</Height>
        </Rect>
        <LeFromColor>
          <A>30</A>
          <R>255</R>
          <G>0</G>
          <B>0</B>
        </LeFromColor>
        <LeToColor>
          <A>30</A>
          <R>255</R>
          <G>255</G>
          <B>255</B>
        </LeToColor>
        <LightAngle>225</LightAngle>
        <Fill>true</Fill>
        <Caption>Shape 2</Caption>
        <LeTextFont>
          <Size>10</Size>
          <Name>Tahoma</Name>
          <Style>Regular</Style>
        </LeTextFont>
        <LeTextColor>
          <A>255</A>
          <R>255</R>
          <G>0</G>
          <B>0</B>
        </LeTextColor>
        <TextSize>10</TextSize>
      </TextField>
      <Caption>Shape 2</Caption>
    </LeShape>
  </ShapeList>
</ShapeList>

稍后可以使用该 XML 文件通过此项目重新打开,最终用户可以再次编辑他们的绘图。

以下是该项目源代码的解释。

该项目首先使用以下代码在 GUI 上创建一个画布:

<Border Margin="10" CornerRadius="3" Grid.Row="1" Grid.Column="1" Background="Beige">
   <Border.BitmapEffect>
      <DropShadowBitmapEffect />
   </Border.BitmapEffect>
   <Canvas Margin="3" x:Name="DrawingCanvas" Background="AliceBlue" Opacity="1" Visibility="Visible">
   <local:CustomRender Canvas.Top="0" Canvas.Left="0" x:Name="shapeCollection">
    <local:CustomRender.BitmapEffect>
      <DropShadowBitmapEffect />
    </local:CustomRender.BitmapEffect>
   </local:CustomRender>
   </Canvas>
</Border>
         

上面的代码首先创建一个带有阴影的 Border,Border 位于 Grid 控件内,因此它将填充 Grid 的单元格。Border 内部的内容是一个 Canvas 控件,Canvas 内部只有一个 FrameworkElement,我们的 DLL (CustomRender),它只是一个元素,然后我们使用该元素的 DrawingContext,手动绘制所有形状。DrawingContext 类似于 WinForm 的 Graphics 对象。

我们的 CustomRender 只是一个 FrameworkElement,它只接受 Visual 对象。最重要的是,它实现了以下两个函数:

// Provide a required override for the VisualChildrenCount property.
        protected override int VisualChildrenCount
        {
            get { return childrens.Count; }
        }
       // Provide a required override for the GetVisualChild method.
        protected override Visual GetVisualChild(int index)
        {
            if (index < 0 || index >= childrens.Count)
            {
                throw new ArgumentOutOfRangeException();
            }
            return childrens[index];
        }  

然后在我们的代码中,我们只需要将 Visual 对象添加到这个 Visual 对象集合中,.NET Framework 将为我们渲染这个 CustomRender 对象。

我们使用反射将形状添加到我们的控制器类中,首先只创建一个形状,然后将形状的 Visual 对象添加到上面的 CustomRender 类中。

  Point pt = e.GetPosition(myCanvas);

  ConstructorInfo constructor = myTool.GetConstructor(new Type[] { typeof(Point) });
  CurShape = constructor.Invoke(new object[] { pt }) as LeShape;


  shapeCollection.AddObject(CurShape.myVisual);

当我们想要绘制这个形状时,我们可以随时调用以下方法:

  DrawingContext dc = myVisual.RenderOpen();
  Draw(dc);

  if (selected)
  {
     if (bounds.Width > 5 && bounds.Height >5)
     {
         DrawPoints(dc, bounds);
     }
  }
  dc.Close();

DrawingVisual 的 RenderOpen 方法将为我们打开一个 DrawingContext,然后我们可以绘制我们的对象,如果形状被选中,那么我会为它绘制几个跟踪点。完成所有这些操作后,我们必须调用 DrawingContext 的 Close 方法,以告知我们已经完成了此 Visual 的绘制。

这是我的绘图工具的 WPF 版本的原理,如果您感兴趣,也可以在我的 WinForms 版本中获取更多信息。


关注点

在编写代码的过程中,你学到了什么有趣/好玩/令人恼火的东西吗? 你做了什么特别巧妙、疯狂或异想天开的事情吗?

历史

在此处保持您所做的任何更改或改进的实时更新。

© . All rights reserved.