第十章 形状与画刷

一、形状

1、Shape常见属性

 StrokeThickness:边框厚度
Stroke:边框颜色
Fill:内部填充
StrokeDashArray:实线与虚线的比例:
StrokeLineJoin:拐角轮廓
Stretch:确认如何填充可用区域

  Fill:形状拉伸其宽度和高度,从而可以正好适应其容器(如果设置了明确的高度和宽度,该设置就不起作用了)

  None:形状不被拉伸。除非使用Height和Width属性

  Uniform:按比例改变形状的宽度和高度,直至形状到达容器边缘。如果为椭圆使用该值,最终将得到适应窗口的最大的圆。如果为矩形使用该值,将得到尽可能大的正方形

  UniformFill:按比例改变形状的宽度和高度,直到形状填满了整个可用空间的高度和宽度。例如,如果在100X200单位大小的窗口中放置使用此尺寸设置的矩形,将得到200X200单位大小的矩形,并且矩形的一部分会被剪裁  

2、矩形

 <Rectangle Width="300" Height="400" StrokeThickness="10" Stroke="Red" 
            StrokeLineJoin="Round"
            RadiusX="40"
            RadiusY="20"
            >
     <Rectangle.Fill>
         <!--图片-->
         Blue
     </Rectangle.Fill>
 </Rectangle>

 

3、椭圆与Viewbox 

 <Ellipse Stroke="Red" StrokeThickness="10"  Stretch="Uniform"></Ellipse>

 

<Viewbox>
            <!-- 使用 Viewbox 来缩放按钮 -->
            <Button Content="Click Me" Width="200" Height="50" />
 </Viewbox>

  Viewbox 是一个非常有用的容器控件,主要用于根据其自身大小自动调整子元素的缩放比例,以保持其内容的显示效果。无论窗口如何调整大小,Viewbox 内的内容都会按比例缩放,以确保内容始终适应当前的窗口尺寸。

4、线

 <Canvas>
 <!--两点(X1,Y1),(X2,Y2) 一线,其坐标是相对于上一级的布局容器的坐标
     左负右正,上负下正
     StrokeStartLineCap:设置拐角属性,可设置圆角、三角形、正方形
     -->
     <Line Canvas.Left="100"
           Canvas.Top="200"
         StrokeThickness="10" X1="0" Y1="0" X2="100" Y2="100"
           StrokeDashArray="3,1"
           StrokeStartLineCap="Round"
           >
         <!--内部可以使用Stroke属性,添加画刷-->
         <Line.Stroke>
             <ImageBrush ImageSource="/123.png"></ImageBrush>
         </Line.Stroke>
     </Line>
 </Canvas>

 

5、折线

    <Polyline Canvas.Left="200" Canvas.Top="400" Stroke="Red" StrokeThickness="20"
              Points="0 0,1 -100,-100 -20,-60 10"
              StrokeStartLineCap="Round"
              StrokeEndLineCap="Round"
              ></Polyline>

 

6、多边形

        <Polygon Canvas.Left="90" Canvas.Top="150" 
                  Stroke="Red" StrokeThickness="20"
                  Points="0 0,1 -100,-100 -20,-60 10"></Polygon>

 

二、画刷

  画刷支持更改通知,因为它们继承自Freezable类。因此,如果改变了画刷,任何使用画刷的元素都会自动重新绘制自身。
  画刷支持部分透明。为此,只需要修改Opacity属性,使背景能够透过前面的内容进行显示。
  通过SystemBrushes类可以访问这样的画刷:此类画刷使用Windows系统设置为当前计算机定义的首选颜色。

SolidColorBrush:使用单一的连续颜色绘制区域

LinearGradientBrush:使用渐变填充绘制区域,渐变的阴影填充从一种颜色变化到另一颜色(并且,也可以在变化到第3种颜色之后再变化到第4种颜色,依此类推)

RadialGradientBrush:使用径向渐变填充绘制区域,除了是在圆形模式中从中心点向外部辐射渐变之外,这种画剧和线性渐变画剧类似

ImageBrush使用可被拉伸、缩放或平铺的图像绘制区域

DrawingBrush:使用Drawing对象绘制区域,该对象可以包含已经定义的形状和位图

VisualBrush:使用Visual对象绘制区域。因为所有WPF元素都继承自Visual类,所以可使用该画刷将部分用户界面(如按钮的表面)复制到另一个区域。当创建特殊效果时,比如部分反射效果,该画刷特别有用

BitmapCacheBrush:使用从Visual对象缓存的内容绘制区域。这种画剧和VisualBrush类似,但如果需要在多个地方重用图形内容或者频繁地重绘图形内容,这种画剧更高效

1.SolidColorBrush

 最简单的画刷类型是SolidColorBrush,这种画刷填充一种固定、连续的颜色。

        <Border>
            <Border.Background>
                <SolidColorBrush Color="Red" Opacity="0.3"></SolidColorBrush>
            </Border.Background>
        </Border>

 

画刷可以用于Foreground、Fill、Stroke等

<StackPanel>  
  <!--<Border>
        <Border.Background>
            <SolidColorBrush Color="Red" Opacity="0.3"></SolidColorBrush>
        </Border.Background>
    </Border>-->
    <TextBlock Margin="20" Text="文章">
        <TextBlock.Foreground>
            <SolidColorBrush Color="BlanchedAlmond" Opacity="0.3"></SolidColorBrush>
        </TextBlock.Foreground>
    </TextBlock>

    <Rectangle Height="150" Width="300" StrokeThickness="10">
        <Rectangle.Fill>
            <SolidColorBrush Color="Cornsilk" Opacity="0.4"></SolidColorBrush>
        </Rectangle.Fill>

        <Rectangle.Stroke>
            <SolidColorBrush Color="PaleGreen" Opacity="0.9"></SolidColorBrush>
        </Rectangle.Stroke>
    </Rectangle>
</StackPanel>

 

2、LinearGradientBrush

当EndPoint不为1时,可使用SpreadMethod属性进行设置:

默认为Pad填充,Reflect为镜像翻转,Repeat为复制填充

  <Rectangle Width="600" Height="300">
      <Rectangle.Fill>
          <LinearGradientBrush StartPoint="0,0" EndPoint="0,0.5"
                               SpreadMethod="Reflect"
                               >
              <!--SpreadMethod="Reflect":翻转-->
              <GradientStop Color="Red" Offset="0"></GradientStop>
              <GradientStop Color="Blue" Offset="0.5"></GradientStop>
              <GradientStop Color="Green" Offset="1"></GradientStop>
          </LinearGradientBrush>
      </Rectangle.Fill>
  </Rectangle>

 

3、RadialGradientBrush

  <Ellipse Height="400" Width="400">
      <Ellipse.Fill>
          <RadialGradientBrush
              RadiusX="0.6"
              RadiusY="0.6"
              
              GradientOrigin="0.7 0.3"
              ><!--默认0.5-->
              <GradientStop Color="Red" Offset="0"></GradientStop>
              <GradientStop Color="Blue" Offset="1"></GradientStop>
          </RadialGradientBrush>
      </Ellipse.Fill>
  </Ellipse>

 

4、ImageBrush

  使用位图填充区域,可通过ImageSource指定使用的图像

  Viewbox描述希望从源图像上剪裁并使用的矩形部分。前两个数值指定矩形开始的左上角,而后两个数值指定矩形的宽度和高度。Viewbox属性使用的是相对坐标系统,这一坐标系统将图像的左上角指定为(0,0),将右下角指定为(1,1)。 

        <Rectangle Height="300" Width="400">
            <Rectangle.Fill>
                <!--(0.3,0.2)从图像的0.3宽度,0.2高度进行裁剪,然后填充50宽度于60%高度-->
                <ImageBrush ImageSource="/Image/mygo.jpg"
                            Viewbox="0.3 0.2 0.5 0.6"
                            ></ImageBrush>
            </Rectangle.Fill>
        </Rectangle>

 

  ViewporeUnits可以设置平铺图像是根据绝对尺寸还是相对尺寸进行设置

  Viewport设置平铺起始坐标与图像大小,前两个值为坐标  后面则为大小

                <ImageBrush ImageSource="/Image/mygo.jpg"
                            TileMode="Tile"
                            ViewportUnits="RelativeToBoundingBox"
                            Viewport="0 0 0.2 0.2"   
                            ></ImageBrush>
            </Rectangle.Fill>

其中titleMode可用于设置平铺图像的翻转方式:

Title:在可用区域复制图像

FlipX:复制图像,但是垂直翻转每个的第二列

FlipY:复制图像,但是水平翻转每个的第二行

FlipXY:复制图像,但是水平翻转每个的第二行,垂直翻转每个的第二列

 

5、VisualBrush

  VisualBrush画刷不常用,使用这种画刷获取元素的可视化内容,并使用该内容填充任意表面。例如,可使用VisualBrush画刷将窗口中某个按钮的外观复制到同一窗口中的其他位置。然而,复制的按钮不能被单击,也不能通过任何方式与其进行交互。在此只是复制了元素的外观。

 <!--仅复制外观,行为动作不被复制-->
 <Rectangle Height="250" Width="400">
     <Rectangle.Fill>
         <VisualBrush Visual="{Binding ElementName=img}"></VisualBrush>
     </Rectangle.Fill>
 </Rectangle>

 

6、BitmapCacheBrush

 VisualBrush与BitmapCacheBrush区别:

  1、VisualBrush可以平铺,但是BitmapCacheBrush不行

  2、若图像透明度修改,VisualBrush跟随变化,而BitmapCacheBrush不必

  3、BitmapCacheBrush可调节放大倍数 

  <Rectangle Height="100" Width="100">
      <Rectangle.Fill>
          <VisualBrush TileMode="Tile" Viewport="0,0,0.5,0.5" Visual="{Binding ElementName=img}"></VisualBrush>
      </Rectangle.Fill>
  </Rectangle>

  <!--VisualBrush类似,但是不能被平铺-->
  <Rectangle Height="100" Width="100">
      <Rectangle.Fill>
          <BitmapCacheBrush Target="{Binding ElementName=img}"></BitmapCacheBrush>
      </Rectangle.Fill>
  </Rectangle>
   <Rectangle Height="100" Width="100">
       <Rectangle.Fill>
           <BitmapCacheBrush Target="{Binding ElementName=img}">
               <BitmapCacheBrush.BitmapCache>
                   <!--RenderAtScale该值指示应用于位图的缩放比例。-->
                   <BitmapCache RenderAtScale="10"></BitmapCache>
               </BitmapCacheBrush.BitmapCache>
           </BitmapCacheBrush>
       </Rectangle.Fill>
   </Rectangle>

 

7、RotateTransform旋转

 <Canvas>
     <!--RenderTransform:渲染变换-->
     <Rectangle Height="10" Width="80" Fill="Yellow" Stroke="Blue"
        Canvas.Left="100" Canvas.Top="100"/>
     <Rectangle Height="10" Width="80" Fill="Yellow" Stroke="Blue"
                Canvas.Left="100" Canvas.Top="100">
         <Rectangle.RenderTransform>
             <!--Angle:旋转角度
             CemterX/Y:中心点坐标,多使用相对坐标-->
             <RotateTransform Angle="25" CenterX ="45" CenterY="5"/>
         </Rectangle.RenderTransform>
     </Rectangle>

     <Rectangle Height="10" Width="80" Fill="Yellow" Stroke="Blue"
        Canvas.Left="100" Canvas.Top="100">
         <Rectangle.RenderTransform>
             <RotateTransform Angle="50"/>
         </Rectangle.RenderTransform>
     </Rectangle>

     <Rectangle Height="10" Width="80" Fill="Yellow" Stroke="Blue"
Canvas.Left="100" Canvas.Top="100">
         <Rectangle.RenderTransform>
             <RotateTransform Angle="80"/>
         </Rectangle.RenderTransform>
     </Rectangle>
 </Canvas>

 

8、ScaleTransform缩放

  <Rectangle Margin="50" Height="10" Width="80" Fill="Yellow" Stroke="Blue"
             Canvas.Left="100" Canvas.Top="100">
      <Rectangle.RenderTransform>
          <!--ScaleX:水平方向放大,为负数时方向反向
          ScaleX:垂直方向放大,为负数时方向反向
          
          -->
          <ScaleTransform  ScaleX="2" ScaleY="2" CenterX="0.3" CenterY="0.8"/>
      </Rectangle.RenderTransform>
  </Rectangle>

 

9、Opecity

  Opacity属性使元素的所有内容都是部分透明的。OpacityMask属性执是供了更大的灵活性。可使元素的特定区域透明或部分透明,从而实现各种常见的的以及新颖的效果。例如,可使用        OpacityMask属性将形状逐渐褪色到完全透明。

 <Button Canvas.Left="50" Canvas.Top="50" Height="30" Width="100" Content="AAAA">
     <Button.OpacityMask>
         <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
             <GradientStop Offset="0" Color="Black"></GradientStop>
             <GradientStop Offset="1" Color="Transparent"></GradientStop>
         </LinearGradientBrush>
     </Button.OpacityMask>
 </Button>

 

 

三、几何图形与图画

1、简单图像绘制

Path类提供了Data属性接受一个Geometry对象,该对象定义路径包含的一个或多个图形。

不能直接创建Geometry对象,因为Geometry是抽象类,需要使用派生类中的一个进行创建。

<StackPanel>
    <Path  Stroke="Red" Margin="10" StrokeThickness="5" >
        <Path.Data>
            <LineGeometry StartPoint="0,0" EndPoint="100,0"></LineGeometry>
        </Path.Data>
    </Path>

    <Path  Fill="Yellow" Margin="10" StrokeThickness="5" >
        <Path.Data>
            <!--Rect:(0,0)起始点,200,100:宽200,高100-->
            <RectangleGeometry Rect="0,0 200,100"></RectangleGeometry>
        </Path.Data>
    </Path>

    <Path  Fill="Yellow" Margin="10" StrokeThickness="5" >
        <Path.Data>
            <!--RadiusX/Y:X/Y半径,Center:中心点-->
            <EllipseGeometry RadiusX="100" RadiusY="50" Center="400,0"></EllipseGeometry>
        </Path.Data>
    </Path>
</StackPanel>

几何图形定义形状,而路径用于绘制形状。
Geometry对象为形状定义了坐标和尺寸等细节,而Path对象提供了用于绘制形
状的Stroke和Fill画刷。Path类还提供了继承自UIElement基础架构的特性,如鼠标和键盘处理。

 

2、GeometryGroup组合

 <Path Fill="Yellow">
     <Path.Data>
         <GeometryGroup FillRule="EvenOdd">
             <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry>
             <EllipseGeometry RadiusX="50" RadiusY="35" Center="50,50"></EllipseGeometry>
         </GeometryGroup>
     </Path.Data>
 </Path>

 

3、CombineGroup

 <StackPanel>
     <Path Fill="Yellow" Stroke="Blue" Margin="5">
         <Path.Data>
             <!--Union:创建包含两个几何图形所有区域的形状-->
             <CombinedGeometry GeometryCombineMode="Union">
                 <!--第一个形状-->
                 <CombinedGeometry.Geometry1>
                     <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry>
                 </CombinedGeometry.Geometry1>
                 <CombinedGeometry.Geometry2>
                     <EllipseGeometry RadiusX="65" RadiusY="35" Center="85,50"></EllipseGeometry>
                 </CombinedGeometry.Geometry2>
             </CombinedGeometry>
         </Path.Data>
     </Path>

     <Path Fill="Yellow" Stroke="Blue" Margin="5">
         <Path.Data>
             <!--创建包含两个几何图形共有区域的形状-->
             <CombinedGeometry GeometryCombineMode="Intersect">
                 <!--第一个形状-->
                 <CombinedGeometry.Geometry1>
                     <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry>
                 </CombinedGeometry.Geometry1>
                 <CombinedGeometry.Geometry2>
                     <EllipseGeometry RadiusX="65" RadiusY="35" Center="85,50"></EllipseGeometry>
                 </CombinedGeometry.Geometry2>
             </CombinedGeometry>
         </Path.Data>
     </Path>

     <Path Fill="Yellow" Stroke="Blue" Margin="5">
         <Path.Data>
             <!--创建包含两个儿何图形非共有区域的形状。换句话说,就像先合并形状(使用Union),再移除共有的部分(使用Intersect)那样-->
             <CombinedGeometry GeometryCombineMode="Xor">
                 <!--第一个形状-->
                 <CombinedGeometry.Geometry1>
                     <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry>
                 </CombinedGeometry.Geometry1>
                 <CombinedGeometry.Geometry2>
                     <EllipseGeometry RadiusX="65" RadiusY="35" Center="85,50"></EllipseGeometry>
                 </CombinedGeometry.Geometry2>
             </CombinedGeometry>
         </Path.Data>
     </Path>

     <Path Fill="Yellow" Stroke="Blue" Margin="5">
         <Path.Data>
             <!--创建的形状包含第一个儿何图形的所有区域,但不包含第二个几何图形的区域-->
             <CombinedGeometry GeometryCombineMode="Exclude">
                 <!--第一个形状-->
                 <CombinedGeometry.Geometry1>
                     <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry>
                 </CombinedGeometry.Geometry1>
                 <CombinedGeometry.Geometry2>
                     <EllipseGeometry RadiusX="65" RadiusY="35" Center="85,50"></EllipseGeometry>
                 </CombinedGeometry.Geometry2>
             </CombinedGeometry>
         </Path.Data>
     </Path>
 </StackPanel>

 

禁止吸烟标志

 <Path Fill="Yellow" Stroke="Blue">
     <Path.Data>
         <CombinedGeometry GeometryCombineMode="Union">
             <CombinedGeometry.Geometry1>
                 <CombinedGeometry GeometryCombineMode="Exclude">
                     <CombinedGeometry.Geometry1>
                         <EllipseGeometry RadiusX="50" RadiusY="50" Center="50,50"></EllipseGeometry>
                     </CombinedGeometry.Geometry1>

                     <CombinedGeometry.Geometry2>
                         <EllipseGeometry RadiusX="40" RadiusY="40" Center="50,50"></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>

 

4、PathGeometry绘制曲线和直线

  PathGeometry是功能超级强大的图形,它能绘制其他所有几何图形能够绘制的内容,也能绘制其他所有几何图形所不能绘制的内容。它的唯一缺点是语法比较长(并且在某种程度上更加复杂)

  每个PathGeometry对象都是由一个或多个PathFigure对象构建的(存储在PathGeometry.Figures集合中)。每个PathFigure对象是一系列相互连接的直线和曲线,可闭合也可不闭合。如果图形中最后一条直线的终点连接到了第一条直线的起点,那么图形就是闭合的。

  <StackPanel>
      <!--直线-->
      <Path Stroke="Blue">
          <Path.Data>
              <PathGeometry>
                  <PathFigure StartPoint="10,100" IsClosed="True">
                      <LineSegment Point="100,100"></LineSegment>
                      <LineSegment Point="100,50"></LineSegment>
                  </PathFigure>
              </PathGeometry>
          </Path.Data>
      </Path>

      <!--曲线-->
      <Path Margin="20" Stroke="DarkBlue">
          <Path.Data>
              <PathGeometry>
                  <PathFigure StartPoint="10,100">
                      <!--Size代表该弧线所在椭圆的X/Y轴的半径
                              IsLargeArc:椭圆两个点最大的曲线
                              SweepDirection:翻转状态
                      -->
                      <ArcSegment IsLargeArc="True" SweepDirection="Clockwise" Point="250,150" Size="100,150"></ArcSegment>
                  </PathFigure>
              </PathGeometry>
          </Path.Data>
      </Path>

      <Path Margin="20" Stroke="DarkBlue">
          <Path.Data>
              <PathGeometry>
                  <PathFigure StartPoint="10,100">
                      <BezierSegment Point1="130,30" Point2="40,140" Point3="150,150"></BezierSegment>
                  </PathFigure>
              </PathGeometry>
          </Path.Data>
      </Path>
  </StackPanel>

 

5、微语言几何图形

  

image

 

   <Path Stroke="Blue" Data="M10,100 L100,100 L100,50 Z"></Path>

 

6、使用几何图形裁剪

  可以裁剪图像、按钮等UIElement

 <Window.Resources>
     <GeometryGroup x:Key="clipElip" 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>
         <ColumnDefinition></ColumnDefinition>
     </Grid.ColumnDefinitions>

     <Button Grid.Column="2" Clip="{StaticResource clipElip}">按钮</Button>
</Grid>

 

posted @ 2025-12-22 23:47  nonAny  阅读(6)  评论(0)    收藏  举报