WPF学习笔记“形状”二:几何图形和图画

  主要是通过Path类来实现;

  路径和几何图形:几何图形定义形状,而路径用于绘制形状。因此Geometry对象为形状定义了坐标、尺寸等细节,而Path对象提供了绘制形状将是用的Stroke和Fill画刷。

  Path类还提供了继承自UIElement基础架构中的特性,如鼠标和键盘处理;

  几何图形类都继承自Freezable类(通过Geometry基类),所以它们支持更改通知,因此如果使用几何图形创建了一个路径,然后修改该几何图形,路经就会自动被重新绘制

。还可以使用几何图形类定义能够通过画刷应用的图画,从而为绘制不需要Path类所具有的用户交互功能的复杂内容提供了一种简单的方法。

   一、基本Path类使用方法代码:

View Code
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="800" Width="500"
      
        x:Name="WindowName">
    <!--使用资源对Path进行重用1-->
    <Window.Resources>
        <GeometryGroup x:Key="geometry">
            <RectangleGeometry Rect="0 0 200 50"></RectangleGeometry>
            <EllipseGeometry Center="50 50" RadiusX="35" RadiusY="35"></EllipseGeometry>
        </GeometryGroup>
    </Window.Resources>
    <StackPanel>
        <!--使用2DShape类创建一个矩形-->
        <Rectangle Width="100" Height="50" Fill="Yellow" Stroke="Black"></Rectangle>
        <!--使用Path类创建一个矩形-->
        <Path Fill="Yellow" Stroke="Black">
            <Path.Data>
                <RectangleGeometry Rect="200 0 100 50" RadiusX="10" RadiusY="10"></RectangleGeometry>
            </Path.Data>
        </Path>
        <!--使用2DShape类创建一条直线-->
        <Line Stroke="Black" X1="0" Y1="0" X2="100" Y2="50" StrokeThickness="10" StrokeStartLineCap="Triangle" StrokeEndLineCap="Round"></Line>
        <!--使用Path类创建一条直线-->
        <Path Fill="Black" Stroke="Yellow" StrokeThickness="10" StrokeStartLineCap="Round" StrokeEndLineCap="Triangle">
            <Path.Data>
                <LineGeometry StartPoint="0 0" EndPoint="100 50"></LineGeometry>
            </Path.Data>
        </Path>
        <!--使用GeometryGroup组和形状-->
        <!--使用一个元素代替了两个元素,这意味着降低了用户界面的开销。通常,使用数量更少的较复杂几何图形元素的窗口比具有大量较简单的几何图形元素的窗口的性能更高-->
        <!--将多个图形组合成一个单独的Path元素也有缺点,不能单独的为不同的形状执行事件处理,反而,Path元素将引发所有的鼠标事件,不过,仍然可以独立的控制嵌套的两个对象,从而改变整个路径。-->
        <Path Fill="Yellow" Stroke="Black" Margin="5">
            <Path.Data>
                <GeometryGroup>
                    <RectangleGeometry Rect="0 0 200 50"></RectangleGeometry>
                    <EllipseGeometry Center="50 50" RadiusX="35" RadiusY="35"></EllipseGeometry>
                </GeometryGroup>
            </Path.Data>
        </Path>
        
        <!--使用资源对Path进行重用2-->
        <Path Fill="Red" Data="{StaticResource geometry}">
        </Path>
        <Path Fill="AliceBlue">
            <Path.Data>
                <StaticResource ResourceKey="geometry"></StaticResource>
            </Path.Data>
        </Path>
    </StackPanel>
</Window>

  二、使用Path类对图形进行融合的代码:

    只用使用CombinedGeometry属性:

  GeometryGroup类是一款非常有价值的工具,但是它也具有明显的局限性。如果是绘制一个形状,并在内部“减去”另一个形状来创建一个新形状,GeometryGroup类可以

工作得很好,然而,如果形状的边界相互交互,就很难得到所希望的结果了,并且如果希望移除形状的一部分,GeometryGroup了就不能提供任何帮助了。

  因此,CombinedGeometry类使用Geometry1和Geometry2两个属性提供者两个几何图形。

View Code
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="800" Width="500"
      
        x:Name="WindowName">
    <StackPanel>
        <StackPanel>
            <!--组合两个图形-->
            <Path Fill="Red" Stroke="Black" Margin="5">
                <Path.Data>
                    <CombinedGeometry GeometryCombineMode="Union">
                        <CombinedGeometry.Geometry1>
                            <RectangleGeometry Rect="0 0 200 50"></RectangleGeometry>
                        </CombinedGeometry.Geometry1>
                        <CombinedGeometry.Geometry2>
                            <EllipseGeometry Center="50 50" RadiusX="35" RadiusY="35"></EllipseGeometry>
                        </CombinedGeometry.Geometry2>
                    </CombinedGeometry>
                </Path.Data>
            </Path>
            <!--组合多个图形-->
            <!--CombinedGeometry对象不会影响用于为形状着色的填充画刷或画笔,这些细节由路径设置,因此如果希望为路径的各部分使用不同的颜色,需要创建相互独立的Path对象-->
            <Path Fill="Yellow" Stroke="Blue">
                <Path.Data>
                    <CombinedGeometry GeometryCombineMode="Union">
                        <CombinedGeometry.Geometry1>
                            <CombinedGeometry GeometryCombineMode="Exclude">
                                <CombinedGeometry.Geometry1>
                                    <EllipseGeometry Center="50 50" RadiusX="50" RadiusY="50"></EllipseGeometry>
                                </CombinedGeometry.Geometry1>
                                <CombinedGeometry.Geometry2>
                                    <EllipseGeometry Center="50 50" RadiusX="40" RadiusY="40"></EllipseGeometry>
                                </CombinedGeometry.Geometry2>
                            </CombinedGeometry>
                        </CombinedGeometry.Geometry1>
                        
                        <CombinedGeometry.Geometry2>
                            <RectangleGeometry Rect="44 5 10 90">
                                <RectangleGeometry.Transform>
                                    <RotateTransform Angle="45" CenterX="50" CenterY="50"></RotateTransform>
                                </RectangleGeometry.Transform>
                            </RectangleGeometry>
                        </CombinedGeometry.Geometry2>
                    </CombinedGeometry>
                </Path.Data>
            </Path>
        </StackPanel>
    </StackPanel>
</Window>

  三、使用PathGeometry绘制曲线和直线:

    PathGeometry是功能超级强大的图形,它能够绘制其他所有几何图形能够绘制的内容,并且也能绘制其他所有几何图形所不能绘制的内容,它的唯一缺点是语法比较长;

    每个PathGeometry对象都是由一个或多个PathFigure对象构建的,每个PathFigure对象是一系列相互连接的直线和曲线,可以闭合也可以不闭合。

    PathFigure类的属性:

              StartPoint(指示从何处开始绘制图形的Point对象)、

              Segments(用于绘制图形的PathSegments对象的集合)、

              IsClosed(连接开始点和结束点)、

              IsFilled(Path.Fill画刷填充图形内部的区域);

    PathSegment类的属性:

              LineSegment(直线)、

              ArcSement(椭圆形弧线)、

              BezierSegment(贝塞尔曲线)、

              QuaDraticBezierSegment(贝塞尔曲线,计算速度快)、

              PolyLineSegment(一系列直线)、

              PolyBezierSegment(一系列贝塞尔曲线)、

              PolyQuadraticBezierSegment(一系列二次贝塞尔曲线);

  

View Code
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="800" Width="500"
      
        x:Name="WindowName">
    <StackPanel>
        <!--绘制一条线-->
        <Path Stroke="Black">
            <Path.Data>
                <PathGeometry>
                    <PathFigure IsClosed="False" StartPoint="10 10">
                        <LineSegment Point="20 20"></LineSegment>
                        <LineSegment Point="0 60"></LineSegment>
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
        </Path>
        <!--绘制一条曲线-->
        <Path Stroke="Red">
            <Path.Data>
                <PathGeometry>
                    <PathFigure IsClosed="False" StartPoint="10 100">
                        <!--size属性提供了椭圆的X半径和Y半径,椭圆越大,曲线就越缓和-->
                        <ArcSegment Point="70 50" Size="30 20" IsLargeArc="False" SweepDirection="Counterclockwise"></ArcSegment>
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
        </Path>
        <Grid>
            <!--绘制贝塞尔曲线-->
            <Path Stroke="Blue">
                <Path.Data>
                    <PathGeometry>
                        <PathFigure StartPoint="40 40">
                            <BezierSegment Point1="50 80" Point2="80 50" Point3="100 100"></BezierSegment>
                        </PathFigure>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path Stroke="Red">
                <Path.Data>
                    <LineGeometry StartPoint="40 40" EndPoint="50 80"></LineGeometry>
                </Path.Data>
            </Path>
            <Path Stroke="Red">
                <Path.Data>
                    <LineGeometry StartPoint="80 50" EndPoint="100 100"></LineGeometry>
                </Path.Data>
            </Path>
        </Grid>
    </StackPanel>
</Window>

  四、微语言几何图形

    复杂的曲线可能由设计工具生成,而不是通过手工编写,所以保持标记的清晰性并不是最重要的,为了保持标记的清晰性,WPF创作人员为定义几何图形增加了一个

  更简明的替换语法,通过该语法可以用更少的标记表示详细的图形。这种语法通常称为图形微语言,并且由于它应用于Path元素;

    

View Code
<Path Stroke="Black">
            <Path.Data>
                <PathGeometry>
                    <PathFigure IsClosed="True" StartPoint="10 10">
                        <LineSegment Point="30 30"></LineSegment>
                        <LineSegment Point="55 15"></LineSegment>
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
        </Path>
        <Path Stroke="Black" Data="M 10, 10 L 30, 30 L 55, 15 Z"></Path>

    

  五、使用几何图形进行剪裁

    几何图形的另一个用途是用于设置Clip属性,所有元素都提供了该属性;通过Clip属性可以结束元素的外边界,以符合特定的几何图形。可以使用Clip属性创建大量的

  特殊效果。尽管该属性通常用于修剪Image元素中的图像内容,但是也可以将Clip属性应用于任何元素。唯一的限制是,如果确实希望看到一些内容---而不仅仅是没有多

  大用处的单独的曲线和线段,需要使用闭合的几何图形;

    

View Code
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="800" Width="500"
      
        x:Name="WindowName">
    <Window.Resources>
        <GeometryGroup x:Key="clipGeometry" FillRule="Nonzero">
            <EllipseGeometry RadiusX="75" RadiusY="50" Center="100 150"></EllipseGeometry>
            <EllipseGeometry RadiusX="100" RadiusY="25" Center="200 150"></EllipseGeometry>
            <EllipseGeometry RadiusX="75" RadiusY="130" Center="140 140"></EllipseGeometry>
        </GeometryGroup>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Button Clip="{StaticResource clipGeometry}" Background="Yellow">A button</Button>
        <Image Grid.Column="1" Clip="{StaticResource clipGeometry}" Stretch="None" Source="/WpfApplication1;component/Images/Penguins.jpg"></Image>
    </Grid>
 </Window>

    使用剪裁存在一个限制,设置的剪裁不会考虑元素的尺寸,也就是显示的按钮变得更大或更小,但是剪裁区域仍然保留原样,并显示按钮的不同部分;

    一个可能的解决方案是在Viewbox控件中包装元素,以便提供自动重新缩放功能。但这会导致所有内容都按比例地改变尺寸,包括希望改变尺寸的一些细节以及那些不

  可能不希望改变的内容;

  六、画图

    抽象的Geometry类表示了一个形状和路径,抽象的Drawing类扮演了一个互补的角色,它表示一个2D图形,也就是它包含了显示一个矢量图形或一幅位图所有信息;

    但是只有GeometryDrawing类可以使用几何图形;

    可将GeometryDrawing对象视为一个矢量插图中的一个形状,

    

View Code
<Window x:Class="Drawing.Drawings"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Drawings" Height="300" Width="300"
    >
  <Window.Resources>
    <GeometryDrawing x:Key="Drawing" Brush="Yellow" >
      <GeometryDrawing.Pen>
        <Pen Brush="Blue" Thickness="3"></Pen>
      </GeometryDrawing.Pen>
      <GeometryDrawing.Geometry>
        <PathGeometry>
          <PathFigure IsClosed="True" StartPoint="10,100">
            <LineSegment Point="100,100" />
            <LineSegment Point="100,50" />
          </PathFigure>
        </PathGeometry>
      </GeometryDrawing.Geometry>
    </GeometryDrawing>
  </Window.Resources>
  
  <StackPanel Orientation="Horizontal" Margin="5">
    <Button Width="30" Height="30">
      <Image>
        <Image.Source>
          <DrawingImage Drawing="{StaticResource Drawing}">            
          </DrawingImage>
        </Image.Source>
      </Image>
    </Button>
    <Button Width="30" Height="30">
      <Button.Background>
        <DrawingBrush Stretch="Uniform" Viewport="0,0 0.9,1" Drawing="{StaticResource Drawing}">          
        </DrawingBrush>
      </Button.Background>
    </Button>
  </StackPanel>
</Window>

 

  七、显示图画

  八、导出插图

     常用工具:

    http://www.mikeswanson.com/XAMLExport

    http://www.mikeswanson.com/swf2xaml

    Expression Design,Microsoft公司的插图和图形设计程序;


 

posted on 2012-10-17 23:35  紫雨心  阅读(812)  评论(0编辑  收藏  举报

导航