【WPF學習】第四十三章 路徑和幾何圖形

  前面四章介紹了繼承自Shape的類,包括Rectangle、Ellipse、Polygon以及Polyline。但還有一個繼承自Shape的類還沒有介紹,並且該類是到如今爲止功能最強大的形狀類,即Path類。Path類可以包含任何簡單形狀、多組形狀以及更復雜的要素,如曲線。架構

  Path類提供了Data屬性,該屬性接受一個Geometry對象,該對象定義路徑包含的一個或多個圖形。不能直接建立Geometry對象,由於Geometry是抽象類,並且須要使用下表中列出的7個派生類的一個進行建立。ide

表 幾何圖形類工具

 

 

   如今,可能會好奇路徑和幾何圖形之間到底有什麼區別。幾何圖形定義形狀,而路徑用於繪製形狀。所以,Geometry對象爲形狀定義了座標和尺寸等細節,而Path對象提供了用於繪製形狀的Stroke和Fill畫刷。Path類還提供了繼承自UIElement基礎架構的特性,若是鼠標和鍵盤處理。oop

  然而,幾何圖形並不像看起來那麼簡單。緣由之一是他們都繼承自Freezable類(經過Geometry基類),因此支持更改通知。所以,若是使用集合圖形建立路徑,而後修改幾何圖形,就會自動被從新繪製路徑。還可使用幾何圖形類來定義可以經過畫刷應用的圖畫,從而爲繪製不須要Path類所具備的用戶交互功能的複雜內容提供一種簡單方法。性能

1、直線、矩形和橢圓圖形spa

  LineGeometry、RectangleGeometry以及EllipseGeometry類直接對應於Line、Rectangle以及Ellipse形狀。例如,可將下面使用Rectangle元素的標記:設計

<Rectangle Fill="Yellow" Stroke="Blue" Width="100" Height="50"></Rectangle>

  轉換爲下面使用Path元素的標記:code

<Path Fill="Yellow" Stroke="Blue">
            <Path.Data>
                <RectangleGeometry Rect="0 0 100,50"></RectangleGeometry>
            </Path.Data>
</Path>

  惟一的實質性區別是Rectangle形狀使用的是Height和Width值,而RectangleGeometry圖形使用4個數值來描述矩形的尺寸和位置。前兩個數值描述左上角的X和Y座標,然後兩個數值設置爲矩形的寬度和高度。可在(0,0)點開始繪製矩形,從而獲得與普通的Rectangle元素相同的效果,或者使用不一樣的值偏移矩形。RectangleGeometry類還提供了RadiuX和RadiuY屬性,這兩個屬性用於圓滑拐角。orm

  相似地,可將下面的Line形狀:xml

 <Line Stroke="Blue" X1="0" Y1="0" X2="50" Y2="10"></Line>

  轉變成下面的LineGeometry圖形:

<Path Stroke="Blue" Fill="Yellow">
            <Path.Data>
                <LineGeometry StartPoint="0,0" EndPoint="50,10"></LineGeometry>
            </Path.Data>
        </Path>

  也可將以下的Ellipse形狀:

<Ellipse Fill="Yellow" Stroke="Blue" Width="100" Height="50" HorizontalAlignment="Left"></Ellipse>

  轉變成下面的EllipseGeometry圖形:

<Path Fill="Yellow" Stroke="Blue">
            <Path.Data>
                <EllipseGeometry RadiusX="50" RadiusY="25" Center="50,25"></EllipseGeometry>
            </Path.Data>
</Path>

  注意,兩個半徑值只是寬度和高度值得一半。還可以使用Center屬性偏移橢圓的位置。在該例中,中心被設置爲橢圓外包圍框的正中心位置,因此使用與繪製Ellipse形狀徹底相同的方式來繪製橢圓圖形。

  總之,這些簡單圖形和對應的形狀使用相同的工做方式。雖然具備額外的可偏移矩形和橢圓的功能,但若是在Canvas面板上放置形狀,該功能是沒有必要的,由於已經具備將形狀定位到特定位置的能力。實際上,若是這就是圖形所能完成的全部內容,可能以爲使用Path元素很煩人。

2、使用GeometryGroup組合形狀

  組合圖形最簡單的方法是使用GeometryGroup對象,該對象在內部嵌套其餘Geometry類的派生類對象。下面的示例在一個正方形的旁邊放置了一個橢圓:

<Path Fill="Yellow" Stroke="Blue" Margin="5" Canvas.Top="10" Canvas.Left="10" >
            <Path.Data>
                <GeometryGroup>
                    <RectangleGeometry Rect="0 0 100 100"></RectangleGeometry>
                    <EllipseGeometry Center="50 50" RadiusX="35" RadiusY="25"></EllipseGeometry>
                </GeometryGroup>
            </Path.Data>
</Path>

  效果圖以下所示:

 

 

   上面標記的效果和以下兩個Path元素的效果相同,其中一個Path元素具備RectangleGeometry,而另外一個Path元素具備EllipseGeometry(並且像是改用Rectangle和Ellipse形狀)。然而,這兩種方法有一個優勢。用一個元素替代了兩個元素,這意味着下降了用戶界面的開銷。一般,使用數量更少的較複雜集合圖形元素的窗口比具備大量較簡單集合圖形元素的窗口的性能要高。在只有幾十個形狀的窗口中這一效果並不明顯,但對於須要幾百或幾千個形狀的窗口,這一問題就會變得更重要了。

  固然,將多個幾何圖形組合成單獨的Path元素也存在缺點——不能單獨爲不一樣的形狀執行事件處理。反而,Path元素將引起全部的鼠標事件。不過,仍能夠獨立地控制嵌套的RectangleGeometry和EllipseGeometry對象,從而改變整個路徑。例如,每一個幾何圖形都提供了Transform屬性,可以使用該屬性拉伸、扭曲和選擇路徑的響應部分。

  幾何圖形的另外一個優勢是可在幾個獨立的Path元素中重用相同的幾何圖形。這不須要使用代碼——只須要在Resources結合中定義集合圖形,並使用StaticExtension或DynamicExtension標記擴展在路徑中進行引用。下面的例子對前面顯示的例子進行了重寫,在Canvas容器的兩個不一樣位置使用兩種相同顏色來顯示CombinedGeometry實例:

<Window x:Class="Drawing.CombiningShapes"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CombiningShapes" Height="300" Width="300">
    <Window.Resources>
        <GeometryGroup x:Key="Geometry">
            <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry>
            <EllipseGeometry Center="150,50" RadiusX="35" RadiusY="25"></EllipseGeometry>
        </GeometryGroup>
    </Window.Resources>
    <Canvas>
        <Path Fill="Yellow" Stroke="Blue" Margin="5" Canvas.Top="10" Canvas.Left="10"
              Data="{StaticResource Geometry}">
        </Path>
        <Path Fill="Yellow" Stroke="Blue" Margin="5" Canvas.Top="150" Canvas.Left="10"
              Data="{StaticResource Geometry}">
        </Path>
    </Canvas>
</Window>
CombiningShapes

 

 

   當形狀相互交叉時,GeometryGroup將更有趣。這時不能將圖畫簡單地做爲固定形狀的組合對待,GeometryGroup使用FillRule屬性(該屬性可設置爲EventOdd或Nonzero)決定填充哪些形狀。若是採用以下方式改變前面顯示的標記,在正方形的上面放置橢圓,分析一下會出現什麼狀況:

<Path Fill="Yellow" Stroke="Blue" Margin="5" Canvas.Top="10" Canvas.Left="10" >
            <Path.Data>
                <GeometryGroup>
                    <RectangleGeometry Rect="0 0 100 100"></RectangleGeometry>
                    <EllipseGeometry Center="50 50" RadiusX="35" RadiusY="25"></EllipseGeometry>
                </GeometryGroup>
            </Path.Data>
        </Path>

  如今,上面的標記建立了一個正方形,這個正方形的內部有一個橢圓形狀的空洞。若是將FillRule屬性修改成Nonezero,在純色正方形的上面就會有一個純色的橢圓,橢圓和正方形都使用黃色填充。

  經過在正方形的上面重疊以白色填充的橢圓,可建立有洞得正方形。然而,若是在下面有內容,GeometryGroup類會變得更有用處。由於在你的形狀中橢圓被視爲洞,後面的內容均可透過該洞顯示。以下示例所示:

 <Canvas>
        <TextBlock Canvas.Top="50" Canvas.Left="20" FontSize="25" FontWeight="Bold">Hello There</TextBlock>

        <Path Fill="Yellow" Stroke="Blue" Margin="5" Canvas.Top="10" Canvas.Left="10" >
            <Path.Data>
                <GeometryGroup>
                    <RectangleGeometry Rect="0 0 100 100"></RectangleGeometry>
                    <EllipseGeometry Center="50 50" RadiusX="35" RadiusY="25"></EllipseGeometry>
                </GeometryGroup>
            </Path.Data>
        </Path>

    </Canvas>
GroupGeometry

 

 

 3、使用CombinedGeometry融合幾何圖形

  對於經過基本圖元(矩形、橢圓和直線)構建複雜形狀,GeometryGroup類是很是有價值的工具。但它也有明顯的侷限性。若是是繪製形狀,並在其內部「減去」另外一個形狀來建立新的形狀,GeometryGroup類能夠工做的很好。然而,若是形狀的邊界相互交叉,就很可貴到所但願的結果了,而且若是但願移除形狀的一部分,GeometryGroup類就不能提供任何幫助了。

  CombinedGeometry類專門用於組合重疊到一塊兒而且不相互包含的形狀。與GeometryGroup類不一樣,CombinedGeometry類只使用兩個幾何圖形,經過Geometry1和Geometry2屬性提供這兩個幾何圖形。CombinedGeometry類沒有包含FillRule屬性,反而具備功能更強大的GeometryCombineMode屬性,該屬性可使用4個值中的一個,下表列出了這4個值。

表 GeometryCombineMode枚舉值

 

 

   例如,下面的示例演示了GeometryCombineMode:

<Window x:Class="Drawing.CombineGeometryShapes"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CombineGeometryShapes" Height="481" Width="341">
    <Window.Resources>
        <RectangleGeometry x:Key="rect" Rect="0 0 100 100"></RectangleGeometry>
        <EllipseGeometry x:Key="ellipse" Center="85 50" RadiusX="65" RadiusY="35"></EllipseGeometry>
    </Window.Resources>
    <Grid Margin="5" TextBlock.FontSize="16">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <Path Fill="Yellow" Stroke="Blue" Margin="5">
            <Path.Data>
                <CombinedGeometry GeometryCombineMode="Union"
            CombinedGeometry.Geometry1="{StaticResource rect}"
            CombinedGeometry.Geometry2="{StaticResource ellipse}">
                </CombinedGeometry>
            </Path.Data>
        </Path>
        <TextBlock Grid.Column="1" Margin="10" VerticalAlignment="Center">Union</TextBlock>

        <Path Grid.Row="1" Fill="Yellow" Stroke="Blue" Margin="5">
            <Path.Data>
                <CombinedGeometry GeometryCombineMode="Intersect"
            CombinedGeometry.Geometry1="{StaticResource rect}"
            CombinedGeometry.Geometry2="{StaticResource ellipse}">
                </CombinedGeometry>
            </Path.Data>
        </Path>
        <TextBlock Grid.Row="1" Grid.Column="1" Margin="10" VerticalAlignment="Center">Intersect</TextBlock>

        <Path Grid.Row="2" Fill="Yellow" Stroke="Blue" Margin="5">
            <Path.Data>
                <CombinedGeometry GeometryCombineMode="Xor"
            CombinedGeometry.Geometry1="{StaticResource rect}"
            CombinedGeometry.Geometry2="{StaticResource ellipse}">
                </CombinedGeometry>
            </Path.Data>
        </Path>
        <TextBlock Grid.Row="2" Grid.Column="1" Margin="10" VerticalAlignment="Center">Xor</TextBlock>

        <Path Grid.Row="3" Fill="Yellow" Stroke="Blue" Margin="5">
            <Path.Data>
                <CombinedGeometry GeometryCombineMode="Exclude"
            CombinedGeometry.Geometry1="{StaticResource rect}"
            CombinedGeometry.Geometry2="{StaticResource ellipse}">
                </CombinedGeometry>
            </Path.Data>
        </Path>
        <TextBlock Grid.Row="3" Grid.Column="1" Margin="10" VerticalAlignment="Center">Exclude</TextBlock>

    </Grid>
</Window>
CombineGeometryShapes

 

 

   爲理解這種組合的工做原理,下圖中顯示的簡單的「no"符合(一個有斜槓貫穿其中的圓)。儘管任何一個WPF基本元都與該形狀不一樣,但能夠用CombinedGeometry對象很快裝配出該符號。

<Window x:Class="Drawing.NoSymbol"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="NoSymbol" Height="300" Width="300">
    <StackPanel Margin="5">

        <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>
</Window>
NoSymbol

 

 

 4、使用PathGeometry繪製曲線和直線

  PathGeometry是功能超級強大的圖形,它能繪製其餘全部幾何圖形可以繪製的內容,也能繪製其餘全部幾何圖形所不能繪製的內容。它的惟一缺點是語法比較長(而且在某種程度上更加複雜)。

  每一個PathGeometry對象都是由一個或多個PathFigure對象構建的(存儲在PathGeometry.Figures集合中)。每一個PathFigure對象是一系列相互鏈接的直線和曲線,可閉合也可不閉合。若是圖形中最後一條直線的終點鏈接到了第一條直線的起點,那麼圖形就是閉合的。

  PathFigure類包含4個重要屬性,以下表所示。

表 PathFigure屬性

 

 

   PathFigure對象是由包含大量線段的不間斷線條繪製的形狀。然而,技巧是有幾種類型的線段,它們都繼承自PathSegment類。其中一些類比較簡單,如繪製直線的LineSegment類。而另一些類(如BezierSegment類)較爲複雜,能夠繪製曲線。

  可自由地混合並匹配不一樣的線段來構建圖形,下表列出了可供使用的線段類。

表 PathSegment類

  名   稱    說    明 
LineSegment 在兩點之間建立直線
ArcSegment 在兩點之間建立橢圓形弧線
BezierSegment 在兩點之間建立貝塞爾曲線
QuadraticBezierSegment 建立形式更簡單的貝塞爾曲線,只有一個控制點而不是兩個控制點,而且計算速度更快
PolyLineSegment 建立一系列直線。可以使用多個LineSegment對象獲得相同的效果,但使用單個PolyLineSegment對象更簡明
PolyBezierSegment 建立一系列貝塞爾曲線
PolyQuadraticBezierSegment 建立一系列更簡單的二次貝塞爾曲線

  一、直線

  使用LineSegment和PathGeometry類建立簡單的線條很是容易。只須要設置StartPoint屬性,併爲線條中的每部分增長一條LineSegment直線段。LineSegment.Point屬性標識每條線段的結束點。

  例如,下面的標記是從點(10,100)開始,繪製一條到點(100,100)的直線,而後從點(100,100)開始繪製到點(100,50)的直線。由於PathFigure.IsClosed屬性設置爲true,因此添加的最後一條線段將點(100,50)鏈接到點(0,0)。最後的結果是直角三角形。

<Path Stroke="Blue">
            <Path.Data>
                <PathGeometry>
                    <PathFigure IsClosed="True" StartPoint="0,100">
                        <LineSegment Point="100,100"/>
                        <LineSegment Point="100,50"/>
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
        </Path>

  效果圖以下所示:

 

 

   二、弧線

  弧線比直線更有趣。就像使用LineSegment類時同樣,使用ArcSegment.Point屬性指定弧線段終點。不過,PathFigure從起點(或前一條線段的終點)向弧線的終點繪製一條曲線。這條彎曲的鏈接線實際是橢圓邊緣的一部分。

  顯然,爲了繪製弧線,只有終點是不夠的,由於有許多曲線(一些彎曲程度較緩和,另外一些彎曲的程度更大)可以鏈接這兩點。還須要指定用於繪製弧線的假想橢圓的尺寸。可以使用ArgSegment.Size屬性完成工做,該屬性提供了橢圓的X半徑和Y半徑。假想的橢圓越大,邊緣曲線就越緩和。

  下面的示例建立了弧線。

<Path Stroke="Blue">
            <Path.Data>
                <PathGeometry>
                    <PathFigure StartPoint="0,100" IsClosed="False">
                        <ArcSegment Point="200,100" Size="200,300"></ArcSegment>
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
        </Path>

 

 

   到目前爲止,弧線聽起來彷佛很簡單。然而,即便提供了起點、終點以及橢圓的尺寸,也仍不具有明確繪製弧線所需的所有信息。上面的示例還依賴與兩個默認值,若是喜歡的話,也可使用其餘值。

  爲了理解該問題,須要分析能鏈接相同兩點的弧線的其餘方式。若是繪製橢圓上的兩個點,顯示能夠由兩種方式鏈接它們——經過沿着短邊鏈接兩點,或沿着長邊鏈接兩點。

  可用ArgSegment.IsLargeArc屬性何止弧線的方向,可將該屬性設置爲true或false。默認是false,這意味着使用兩條弧線中較短的一條。

  即便設置了方向,也還有一點須要明確——橢圓位於何處。設想繪製一條弧線鏈接左邊的一點或右邊的一點,並使用盡量短的弧線。鏈接這兩個點的曲線可被向下拉伸,而後向上拉上拉伸;也能夠翻轉該弧線,從而先向上彎曲,而後向下彎曲。獲得的弧線依賴與定義弧線的兩點的順序以及ArgSegment.SweepDirection屬性,該屬性能夠是Counterclockwise(默認值)或Clockwise。

  三、貝塞爾曲線

  貝塞爾曲線使用更復雜的數學公式鏈接兩條線段,該公式包含的兩個控制點決定了曲線的性質。實際上,貝塞爾曲線是每一個矢量繪圖程序都會建立的要素,由於他們很是靈活。只須要使用起點、終點和兩個控制點。就能夠建立出使人稱奇的各類光滑曲線(包括回線(loop))。以下圖所示,顯示了一條經典的貝塞爾曲線,兩個小圓指示了控制點而曲線將每一個控制點鏈接到受控制點影響最大的線條端點。

<Window x:Class="Drawing.BezierCurve"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="BezierCurve" Height="300" Width="300">
    <Canvas>
        <Path Stroke="Blue" StrokeThickness="5" Canvas.Top="20">
            <Path.Data>
                <PathGeometry>
                    <PathGeometry.Figures>
                        <PathFigure StartPoint="10,10">
                            <BezierSegment Point1="130,30" Point2="40,140" Point3="150,150"></BezierSegment>
                        </PathFigure>
                    </PathGeometry.Figures>
                </PathGeometry>
            </Path.Data>
        </Path>
        <Path Stroke="Green" StrokeThickness="2" StrokeDashArray="5 2" Canvas.Top="20">
            <Path.Data>
                <GeometryGroup>
                    <LineGeometry StartPoint="10,10" EndPoint="130,30"></LineGeometry>
                    <LineGeometry StartPoint="40,140" EndPoint="150,150"></LineGeometry>
                </GeometryGroup>
            </Path.Data>
        </Path>
        <Path Fill="Red" Stroke="Red" StrokeThickness="8"  Canvas.Top="20">
            <Path.Data>
                <GeometryGroup>
                    <EllipseGeometry Center="130,30"></EllipseGeometry>
                    <EllipseGeometry Center="40,140"></EllipseGeometry>
                </GeometryGroup>
            </Path.Data>
        </Path>
    </Canvas>
</Window>
BezierCurve

 

 

 

   即便不理解貝塞爾曲線的數學原理,也很容易」感受「出貝塞爾曲線的工做原理。本質上,兩個控制點是全部問題的關鍵。他們以兩種方式影響曲線:

  •   在起點,貝塞爾曲線和從第一個控制點到起點之間的直線相切。在終點,貝塞爾曲線和鏈接終點與最後一個點的直線相切(在中間是曲線)
  •   彎曲程度由到兩個控制點的距離決定。若是一個控制點更遠,該控制點會更強地」拉「貝塞爾曲線。

  爲在標記中定義貝塞爾曲線,須要提供三個點。前兩個點(BezierSegment.Point1和BezierSegment.Point2)是控制點,第三個點(BezierSegment.Point3)是曲線的終點。一樣,起點是路徑的起點或前一條線段的終點。

5、微語言幾何圖形

  到目前爲止看到的幾何圖形都比較簡明,只用了少數幾個點。更復雜的集合圖形在該概念上與此相同,只不過動輒就須要幾百條線段。在複雜路徑中定義每條直線、弧線以及曲線很是繁瑣並且不是必需的——畢竟,複雜曲線可能由設計工具生成,而不是經過手工編寫,因此保持標記的清晰性並非最重要的。爲此,WPF創做人員爲定義幾何圖形增長了一種更簡明的替換語法,經過該語法可用更少的標記表示詳細的圖形。這種語法一般稱爲圖形微語言(geometry mini-language),而且因爲應用於Path元素,所以有時候稱爲路徑微語言。

  爲理解微語言,須要認識到它在本質上包含一系列命令的長字符串。這些命令由類型轉換器讀取,而後建立響應的幾何圖形。每一個命令都是單獨的字母,後面可選地跟隨一些由空格分隔的數字信息(如X和Y座標)。每一個命令也使用空格與前面的命令隔開。

  例如,在前面使用具備兩條線路的閉合路徑建立了一個基本三角形,下面是繪製這個三角形的標記:

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

  使用微語言建立該圖形,英按以下方式編寫標記:

<Path Stroke="Blue" Data="M 10,100 L 100,100 L 100,50 Z"/>

  這個路徑使用一個包含4個命令的命令序列。第一個命令(M)建立PathFigure,並將起點設置爲(10,100)。接下來的兩個命令(L)建立線段。最後一個命令(Z)結束PathFigure,並將IsClosed屬性設置爲True。這個字符串中的逗號是可選的,一樣,命令及其參數之間的空格也是可選的,但在相鄰的兩個參數之間以及命令之間至少要保留一個空格。這意味着能夠進一步精簡語法,造成下面這種更難度的形式:

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

  當使用微語言建立集合圖形時,其實是建立了StreamGeometry對象而不是PathGeometry對象。所以,之後在代碼中不能修改圖形。若是這是不能接受的,可顯示地建立PathGeometry對象,但使用相同的語法定義其PathFigure對象集合。以下所示:

<Path Stroke="Blue">
            <Path.Data>
                <PathGeometry Figures="M 10,100 
          L 100,100 L 100,50 Z"></PathGeometry>
            </Path.Data>
        </Path>

  微語言幾何圖形很容易理解。它使用下表中詳細描述的一小組命令。參數以斜體顯示:

表 微語言圖形命令

 

 

 6、使用幾何圖形進行裁剪

  幾何圖形是建立形狀的最強大方法。然而,幾何圖形不只可用於Path元素,也可爲任何須要的地方提供抽象的圖形定義(而不是在窗口中繪製真實的具體形狀)。

  幾何圖形的另外一個用途是用於設置Clip屬性,全部元素都提供了該屬性。能夠經過Clip屬性約束元素的外邊界以符合特定的幾何圖形。可以使用Clip屬性建立大量的特殊效果。儘管該屬性一般用於修剪Image元素中的圖像內容,但也可將Clip屬性應用於任何元素。惟一的限制是,若是確實但願看到一些內容——而不只是用處不大的單獨曲線和線段,須要使用閉合的幾何圖形。

  下面的示例定義了一個集合圖形,該集合圖形用於裁剪兩個元素,一個是包含一副位圖的Image元素,另外一個是標準的Button元素。

 

 

   下面是該例的標記:

<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}">A button</Button>
        <Image Grid.Column="1" Clip="{StaticResource clipGeometry}" 
           Stretch="None"  Source="creek.jpg"></Image>
    </Grid>
Clip

  使用裁剪存在限制。設置的裁剪不會考慮元素的尺寸。換句話說,當改變窗口尺寸時,無論上圖中顯示的按鈕變大仍是變小,裁剪區域仍保留原樣,並顯示按鈕的不一樣部分。一種可能的解決方案是在Viewbox控件中封裝元素,以便提供自動從新縮放功能。但這會致使全部內容都按比例地改變尺寸,包括但願改變尺寸的一些細節(裁剪區域和按鈕表面)以及那些可能不但願改變的內容。

  以下示例使用Viewbox控件所示:

<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>
        <Viewbox >
            <Button Width="350" Height="350" Clip="{StaticResource clipGeometry}">A button</Button>
        </Viewbox>
    </Grid>
ClippingWithViewbox

相關文章
相關標籤/搜索