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

关于 WPF 引擎的可能信息丰富的文章

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (11投票s)

2010年7月2日

CPOL

14分钟阅读

viewsIcon

35591

本文旨在为初学者介绍 WPF,并为中级用户提供一些技巧。

前言

本文概述了 WPF 的图形功能,包括二维和三维形状、字体和动画。作者想强调的是,本文是为初学者准备的。我写这篇文章的原因是 WPF 集成了以前只能在特殊库(如 Microsoft GDI+ 和 DirectX)中使用的绘图和动画功能。WPF 中的图形系统专为您的计算机图形硬件设计,以减轻 CPU 负载,并在许多情况下加快图形渲染速度。因此,就 WPF 本身而言,它确实是一项卓越的技术,它可以读取并评估您机器的显卡通过机器视频接口卡所具备的图形能力。此外,WPF 图形使用分辨率无关的度量单位,使应用程序在不同设备上更加统一和便携。例如,WPF 中元素的尺寸属性以分辨率无关的像素为单位进行测量,其中一个像素代表 1/96 英寸——但这取决于计算机的 DPI(每英寸点数)设置。图形引擎会确定正确的像素数,以便所有用户在所有设备上都能看到相同大小的元素。为了强调图形草图的重要性,我还介绍了 Microsoft Blend SDK 版本 4。

图形元素使用基于矢量的系统在屏幕上渲染,该系统通过计算来确定每个元素的尺寸和缩放方式,以防止过大的元素与正常大小的前景重叠。基本的二维形状是线条、矩形和椭圆。众所周知,WPF 拥有可用于创建自定义形状或曲线的控件。画笔可用于用纯色、复杂图案、图像甚至视频填充元素。

告诉我 XAML 是什么

在 Windows Presentation Foundation 中,屏幕是用一种名为可扩展应用程序标记语言 (XAML) 的 XML 方言构建的。XML 是以数据为中心的,并且被视为一项独立的技术。某些网页上的数据或 Web 服务请求(响应消息)是以 XML 文档的形式存在的。任何数据(任何字母数字字符)都会被标记,因为 XML 的规则非常严格。也就是说,通过 HTML 在页面上标记的控件、图像或任何项目构成了呈现内容。字母或数字通过 XML 被单独标记。其思想是将网页上的呈现内容与数据分开。这会产生一个更炫酷的页面。XAML 比命令式更具声明性。通过声明性,我的意思是控件被指定为一个 XML 元素,具有属性和子元素来描述控件的外观。您不必关心这是如何完成的,因为当您告诉 WPF 您想要什么时,它会在后台弄清楚如何构建控件(实例化对象和分配属性)。这类似于将控件拖放到 Windows 窗体上。部分类允许生成代码,开发人员只需负责编写事件处理程序代码。此外,设计器分为顶部的图形设计表面和底部的 XAML。设计器的工作方式与 Windows 窗体相同,您可以将控件拖放到上面并在属性窗口中进行编辑。但 XAML 是新事物,因此我们必须仔细研究 XAML 并定义 WPF 中使用的一些术语。

检查 XAML

在 Windows 窗体中,所有内容都直接转换为代码。然而,WPF 将其用户界面转换为 XAML,然后在编译时转换为代码。这是一个关键区别:XAML 被编译成一种称为 BAML 的二进制格式。然而,此时不必详细介绍 BAML。只需注意,在 WPF 项目的用户界面设计器中工作时,VS2008 会为所有 UI 元素生成 XAML,而不是代码。

<Window x:Class="MainWindow1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Window1" Height="300" Width="300">
<Grid>
</Grid>
</Window>

XAML 定义了一个具有标题、尺寸和空白网格的窗口。稍后关于布局的部分会解释网格。因为它是 XML,所以您也有命名空间:xmlnsxmlns:x。窗口通常与一个代码隐藏文件相关联,该文件是 C#。但 C# 代码在哪里发挥作用呢?WPF 与 Windows 窗体一样使用事件,因此您需要一个地方来放置处理程序,这就是代码隐藏。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }
}

请注意,代码隐藏中的 Window1 类是 partial 的,并且其构造函数调用 InitializeComponent。在 Windows 窗体中,InititalizeComponent 位于一个单独的文件中,您可以访问该文件。然而,WPF 会从 XAML 生成 InitializeComponent。您会看到,WPF 会确保 XAML 创建一个名为 Window1 的部分类,其中包含一个 InitializeComponent 方法,然后 C# 会合并并编译这些部分。如果您收到一个错误消息,其中 InitializeMethod 被划线,则将鼠标悬停在该划线上,注意错误。会出现一个框,单击该框会为您提供生成“存根方法”以纠正错误的选项。

XAML 中的控件

许多人将使用 WPF 设计器的拖放功能来构建其 UI,但其他人则希望直接在 XAML 中进行操作。要尝试设计器,请将 Label 控件拖放到设计器中的窗口上。如果您打开了拆分窗口,您将在 XAML 中看到 Label 的代码。您可以在 XAML 代码中看到 Label 控件,以及 Label 标签内的文本是如何更改的。Label 上还有一些属性,与您在属性窗口中看到的属性匹配。Name 属性是在代码中用于访问该标签的变量名(如果您需要的话),而 VerticalAlignment 描述了该控件在其父元素中的对齐方式,这意味着此 Label 将在网格的顶部边框内对齐。Margin 稍后在讨论布局时会讲到(它意味着顶部、左侧、右侧和底部边框与包含控件(即 Grid)的距离是我们指定的)。请注意,Content 属性与标签文本匹配,但 XAML 未显示 Content 属性。我们使用的 XAML 是以下内容的快捷方式

<Label Height="28" Margin="80,94,78,0"
       Name="label1" VerticalAlignment="Top">
  <Label.Content>
    What the Heck is XAML?
  </Label.Content>
</Label>
输出

xaml.JPG

如果您只想使用文本,这是最常见的内容,您不需要将文本包装在特定于属性的内容元素中。然而,XAML 控件的一个很酷之处在于它们的组合性。无论它是标签、按钮、文本框还是其他任何类型的控件,您都可以向其中添加任何类型的内容。您只能在一个 Content 元素中放置一个项目,但该项目可以是一个可以容纳多个控件的布局控件。

管理布局

上一节的一个主题是 WPF 如何确定 Label 控件出现在页面上的位置、其大小以及与其他控件的关系。虽然 Windows 窗体应用程序通过锚定和对接提供绝对定位和布局支持,但 WPF 更为复杂,并提供更多选项。对于 WPF,您需要了解控件的对齐和尺寸,边框和边距,以及用于定义包含控件的关系及其出现位置的布局控件。通过 WPF 控件,您可以控制它们的对齐和尺寸。您还可以管理它们的内容、边框和边距,这些通常被称为框模型。WPF 控件的默认行为是拉伸以填充其内容。如果您使用的是 ListBoxGrid,填充整个区域可能是期望的外观,但您可能不希望 ButtonLabel 控件出现这种情况。以下 Label 控件演示了拉伸行为

<Label Name="label1" Background="AliceBlue">
   What the Heck is XAML?
</Label>

Label 没有指定大小或位置的属性,因此默认情况下会拉伸。无论如何,一种常见的布局控件的方式是让它们水平或垂直排列。您可以使用 StackPanel 布局控件来实现这一点。这是一个示例

<StackPanel Orientation="Horizontal">
  <Label>One</Label>
  <Label>After</Label>
  <Label>the Other</Label>
</StackPanel>

xaml2.JPG

您可以向 StackPanel 添加许多项目,就像之前看到的 Label 控件一样,它会将它们排列起来。下面的 XAML 代码展示了它的样子。该示例将 Orientation 属性设置为 Horizontal,但如果省略 Orientation,它将默认为 VerticalUniformGrid 控件将每个单元格的大小平均分配给所有控件。以下示例展示了它的工作原理

<UniformGrid Height="100" Name="uniformGrid1" Width="200">
    <Label>O</Label>
    <Label>X</Label>
    <Label>O</Label>
    <Label>X</Label>
    <Label>O</Label>
    <Label>X</Label>
    <Label>O</Label>
    <Label>X</Label>
    <Label>O</Label>
</UniformGrid>

因为有九个项目,所以网格看起来会像井字棋盘。如果您需要对网格布局进行更精细地控制,则应使用 Grid 布局控件。因此,您需要的另一种布局安排是按表格格式放置项目,即行和列,这就是 Grid 布局的作用。那个 Grid 是空的,但您通常会想创建行和列。下面的代码向您展示了如何使用 Grid

<Window x:Class="Main.Window1"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Title="Window1" Height="300" Width="400">
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0"
    Grid.Column="0"
    Grid.ColumnSpan="3"
    HorizontalAlignment="Center">
    Grid Facts
</Label>
<Label Grid.Row="1" Grid.Column="0">
Width="125"
</Label>
<Label Grid.Row="1" Grid.Column="1">
Absolute Column Width
</Label>
<Label Grid.Row="1" Grid.Column="2">
Grid.Column
</Label>
<Label Grid.Row="2" Grid.Column="0">
Width="2*"
</Label>
<Label Grid.Row="2" Grid.Column="1">
Proportional Spacing
</Label>
<Label Grid.Row="2" Grid.Column="2">
Grid.Column
</Label>
<Label Grid.Row="3" Grid.Column="0">
Width="Auto"
</Label>
<Label Grid.Row="3" Grid.Column="1">
Fill Remaining Space
</Label>
<Label Grid.Row="3" Grid.Column="2">
Grid.Column
</Label>
<Label Grid.Row="4" Grid.Column="0">
Height="25"
</Label>
<Label Grid.Row="4" Grid.Column="1">
Absolute Row Height
</Label>
<Label Grid.Row="4" Grid.Column="2">
Grid.Row
</Label>
<Label Grid.Row="5" Grid.Column="0">
Grid.ColumnSpan="3"
</Label>
<Label Grid.Row="5" Grid.Column="1">
Cover 3 Columns
</Label>
<Label Grid.Row="5" Grid.Column="2">
Control Attribute
</Label>
</Grid>
</Window>

xaml3.JPG

在此代码中首先要注意的两项是 Grid.ColumnDefinitionsGrid.RowDefinitions,它们分别定义了列和行。结合 Label 控件,下面的代码显示了网格线,以便您可以看到大小调整对行和列的影响。这是实现此目的的代码行

<Grid ShowGridLines="True"> 

您可以使用三种设置来控制列的大小:绝对、比例和自动填充。以下是它们的使用方法

<Grid.ColumnDefinitions>
<ColumnDefinition Width="125" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> 

Absolute 设置了明确的宽度,Auto 填充了 Grid 布局的包含控件的其余宽度。Proportional 有点不同,因为它与其它控件的大小成比例。前面示例中的第二列是当前平均列大小的两倍。因此,如果网格容器的宽度是 400,并且有三列,那么一列的平均大小大约是 133。因为比例系数是 2,所以第二列的宽度是 2 x 133 = 266。您也可以对 RowDefinition 元素的 Height 属性使用绝对、比例和自动填充间距。定义了列和行之后,您必须指定控件要放入哪个列和哪个行。此示例使用了所有 Label 控件,但您可以将任何 WPF 控件放入网格中。这是第二行第一列的控件

<Label Grid.Row="1" Grid.Column="0"> 
Width="125"
</Label>

查看 Grid.RowGrid.Column 属性如何引用控件要放入的行和列。您可以查看每个控件,看看它们的显示方式。第一行有一个 Label,它跨越了网格的所有列,如下所示

<Label Grid.Row="0"
  Grid.Column="0"
  Grid.ColumnSpan="3"
  HorizontalAlignment="Center">
Grid Stuff
</Label>

请注意 Grid.ColumnSpan,这意味着该控件覆盖了网格中的所有三列。如果您需要一个控件覆盖多行,您可以使用 Grid.RowSpan 以相同的方式。您还可以使用 HorizontalAlignment 设置内容的水平对齐,或使用 VerticalAlignment 设置垂直对齐。借助 VS2008 中的 IntelliSense 和自动格式设置,这要容易得多。一个有用的功能是,当 XAML 块出现问题时,您可以突出显示该块并按 Ctrl+K+F 进行自动格式设置。如果您不喜欢默认的自动格式设置,可以自行更改。只需选择“工具”、“选项”、“文本编辑器”,然后选择 XAML 分支。您会注意到几个子分支,它们为您提供了有关如何格式化 XAML 的许多选项。如果您一直在使用 Windows 窗体并习惯了对接布局,WPF 会通过 DockPanel 让您保持舒适。您可以使用 DockPanel 将控件定位在客户端区域的顶部、左侧、底部、右侧和中心。这是一个示例

<DockPanel>
<Label DockPanel.Dock="Top"
Background="CornflowerBlue">Top</Label>
<Label DockPanel.Dock="Bottom"
Background="Fuchsia">Bottom</Label>
<Label DockPanel.Dock="Left">Left</Label>
<Label DockPanel.Dock="Right">Right</Label>
<Label Background="Chartreuse">Center</Label>
</DockPanel>

xaml4.JPG

DockPanel 中,除了 Center 之外,每个控件都设置了 DockPanel.Dock 到其占据的客户端区域的侧面。没有 DockPanel.Dock 的控件(如 Center)将填充剩余空间。图像显示了它的样子。背景颜色显示了每个控件所占据的空间。不算太好,但也不算太差。顶部和底部跨越了客户端区域的宽度,因为它们是第一个输入的控件。左侧和右侧占据了剩余空间。如果 Right 在列表中的位置在 Bottom 之前,它将向下延伸到客户端区域的底部,而 Bottom 将停止在 Right 的左边框处。管理布局的概念与网页设计有些相似,HTML(标记)将呈现内容放置在加载到浏览器框架内的网页边界内。在 WPF 中,我们只是管理布局,该布局将决定数据或其他控件可以放置的位置等。

那么我们现在在哪里?

从字体开始

本节代码介绍了如何通过修改 XAML 代码中 TextBlock 控件的字体属性来控制字体。XAML 代码展示了如何使用 TextBlock 以及如何更改属性来控制显示文本的外观。此时显示的这些操作也可以应用于其他基于文本的控件,例如 TextBox

<Window x:Class="UsingFonts.UsingFontsWindow"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Title="UsingFonts" Height="120" Width="400">
   <StackPanel>
      <TextBlock FontFamily="Arial" FontSize="12" 
                 FontWeight="Bold">
         Arial 12 point bold.</TextBlock>
 
      <TextBlock FontFamily="Times New Roman">
         Times New Roman plain, default size.</TextBlock>

      <TextBlock FontFamily="Courier New" FontSize="16"
         FontStyle="Italic" FontWeight="Bold">
         Courier New 16 point bold and italic.
      </TextBlock>

      <TextBlock>
         <TextBlock.TextDecorations>
            <TextDecoration Location="Overline" />
            <TextDecoration Location="Baseline" />
         </TextBlock.TextDecorations>
                Default font with overline and
                baseline.
      </TextBlock>
      <TextBlock>
         <TextBlock.TextDecorations>
            <TextDecoration Location="Strikethrough" />
            <TextDecoration Location="Underline" />
         </TextBlock.TextDecorations>
         Default font with strikethrough and underline.
      </TextBlock>
   </StackPanel>
</Window>

代码隐藏文件是标准的,因为没有事件处理程序,或者更重要的是,没有 RoutedEvent

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace UsingFonts
{
  
   public partial class UsingFontsWindow : Window
   {
      public UsingFontsWindow()
      {
         InitializeComponent();
      }
   }
}

构建构成解决方案容器的这些文件后,我们会得到以下输出

1.JPG

有了这个输出,我们就可以看到它为何有效,但我们应该知道它是如何工作的。您想在 TextBlock 中显示的文本放置在 TextBlock 标签之间。FontFamily 属性定义了显示文本的字体。此属性可以设置为任何字体。定义的行(分隔 TextBlock 字体)分别为 Arial、Times New Roman 和 Courier New。FontSize 属性定义了以点为单位测量的文本大小。当未指定 FontSize 时,该属性设置为系统的默认值。TextBlock 具有各种属性来进一步修改字体。FontWeight 属性可以设置为粗体,使字体更粗。此属性可以设置为数值(1-999)或预定义的描述性值(例如 LightUltraBold)来定义文本的粗细。您可以使用 FontStyle 属性使文本成为 ItalicOblique(一种更强调的斜体)。最后,您还可以为 TextBlock 定义 TextDecorations,在文本上方绘制一条水平线。第四个 TextBlock 中显示的 OverlineBaseline 分别在文本上方和下方创建线。

WPF 有几种内置形状。以下示例 XAML 代码将演示如何显示 LineRectangleEllipse。请检查 XAML 代码

<Window x:Class="BasicShapes.BasicShapesWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       Title="BasicShapes" Height="200" Width="500">
   <Canvas>
      <Rectangle Canvas.Left="90" Canvas.Top="30" 
                Width="150" Height="90"
                Fill="Blue"/>
 
         <Line X1="90" Y1="30" X2="110" 
                 Y2="40" Stroke="Black" />
         <Line X1="90" Y1="120" X2="110" 
                 Y2="130" Stroke="Black" />
         <Line X1="240" Y1="30" X2="260" 
                 Y2="40" Stroke="Black" />
         <Line X1="240" Y1="120" X2="260" 
                 Y2="130" Stroke="Black" />
         <Rectangle Canvas.Left="110" Canvas.Top="40" 
                 Width="150" Height="90" 
                 Stroke="Black" />
 
      <Ellipse Canvas.Left="280" Canvas.Top="75" 
             Width="100" Height="50" Fill="Red" />
      <Line X1="380" Y1="55" X2="380" 
             Y2="100" Stroke="Black" />
      <Line X1="280" Y1="55" X2="280" 
             Y2="100" Stroke="Black" />
      <Ellipse Canvas.Left="280" Canvas.Top="30" 
             Width="100" Height="50"
         Stroke="Black" />
   </Canvas>
</Window>

为完整起见,这里是放置在此的标准代码隐藏文件(不是为了占空间,而是为了举例说明 BasicShapes 的类构造)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BasicShapes
{
   
   public partial class BasicShapesWindow : Window
   {
      public BasicShapesWindow()
      {
         InitializeComponent();
      }
   }
}

此 XAML 代码输出了一些基本形状

2.JPG

请注意,我们使用 Rectangle 元素在窗口中创建了一个填充的矩形。另外请注意,布局控件是 Canvas,允许我们使用坐标来定位形状。要指定 Rectangle 的左上角,我们将附加属性 Canvas.LeftCanvas.Top 分别设置为 90 和 30。然后我们将 WidthHeight 属性分别设置为 150 和 90,以指定大小。要定义 Rectangle 的颜色,我们使用 Fill 属性。

变换:使用 WPF 进行的几次矢量绘图

变换可以应用于任何元素,以重新定位或重新定向图形。有四种类型的变换:TranslateTransformRotateTransformSkewTransformScaleTransformTranslateTransform 将对象移动到另一个位置。RotateTransform 围绕一个点并以指定的 RotationAngle 旋转对象。SkewTransform 使对象倾斜(或扭曲)。ScaleTransform 通过不同的指定量缩放对象的 x 和 y 坐标点。星形是一个多边形。如果我们想绘制一个星形,我们使用 Polygon 元素并使用 RotateTransforms 来创建一个随机颜色的星形圆。请注意,我们使用了“随机”这个词。这是用于生成随机数的类,因此使用了相同的方法。此示例中的 PolygonPoints 属性使用一种新语法定义。这是 XAML

<Window x:Class="DrawStars.DrawStarsWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="DrawStars" Height="330" 
      Width="330" Name="DrawStars">
   <Canvas Name="mainCanvas">
      <Polygon Name="star" Fill="Green" 
                Points="205,150 217,186 259,186         
                  223,204 233,246 205,222 177,246
                  187,204 151,186 193,186" />
   </Canvas>
</Window>

这是代码隐藏文件,它使用 System 命名空间中的 Random 类来生成随机坐标数。这与旋转星形相结合,在用户界面上创建了一个相当不错的图像

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

namespace DrawStars
{
   public partial class DrawStarsWindow : Window
   {
    
      public DrawStarsWindow()
      {
         InitializeComponent();

         Random random = new Random(); 

         // now let's create 18 more random stars
         for ( int count = 0; count < 18; count++ )
         {
            Polygon newStar = new Polygon(); 
            newStar.Points = star.Points; 

            byte[] colorValues = new byte[ 4 ]; 
            random.NextBytes( colorValues );
            newStar.Fill = new SolidColorBrush( Color.FromArgb(
               colorValues[ 0 ], colorValues[ 1 ], colorValues[ 2 ],
               colorValues[ 3 ] ) ); 

            
            RotateTransform rotate =
               new RotateTransform( count * 20, 150, 150 );
            newStar.RenderTransform = rotate;
            mainCanvas.Children.Add( newStar );
         } 
      } 
   } 
}

输出如下

star.JPG

这是在(使用 Expression Blend SDK:Microsoft 矢量图形秘密武器)我绘制了一个带有咬痕的苹果后生成的 XAML 代码。此示例的目的是展示在获得 WPF Sketch Flow 应用程序实用工具的使用经验后,可以将什么导入 Visual Studio 2010(2008)。

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="WpfApplication2.MainWindow"
        x:Name="Window"
        Title="MainWindow"
        Width="447" Height="379">
    <Grid x:Name="LayoutRoot">
    <Canvas x:Name="L5end" HorizontalAlignment="Left" 
      Height="608" UseLayoutRounding="False" 
      VerticalAlignment="Top" Width="786">
 <Canvas x:Name="Finished" Height="217.264" 
      Canvas.Left="78" Canvas.Top="34" 
      Width="265">
<Path Data="F1M378.744,178.918C377.298,179.752,375.053,180.286,
       374.475,182.037L374.475,182.037C374.445,182.125,374.421,182.216,374.4,
       182.314L374.4,182.314C373.904,184.608,376.707,185.631,378.275,
       186.06L378.275,186.06C380.545,186.687,381.509,187.812,382.746,
       189.742L382.746,189.742C383.811,191.404,385.122,192.872,386.217,
       194.51L386.217,194.51C387.347,196.197,388.19,198.056,389.224,
       199.802L389.224,199.802C391.193,203.13,392.886,206.579,394.803,
       209.932L394.803,209.932C395.579,211.291,399.811,221.153,402.461,
       219.625L402.461,219.625C406.568,217.253,396.952,177.703,382.98,
       177.7L382.98,177.7C381.606,177.7,380.193,178.081,378.744,178.918" 
     Height="42.085" Canvas.Left="90.99" 
     Stretch="Fill" Canvas.Top="2.166" Width="29.075">
<Path.Fill>
 <LinearGradientBrush EndPoint="0.533,0.52" StartPoint="0.783,0.422">
 <GradientStop Color="#FFE2BB8F" Offset="0"/>
  <GradientStop Color="#FF946C28" Offset="1"/>
 </LinearGradientBrush>
</Path.Fill>
</Path>
<Path Data="M374.4746,182.0371C374.4456,182.1241,
        374.4206,182.2161,374.4006,182.3131C373.9046,184.6071,376.7066,
        185.6311,378.2756,186.0601C380.5446,186.6871,381.5086,187.8111,
        382.7456,189.7421C383.8116,191.4031,385.1216,192.8721,386.2166,
        194.5101C387.3476,196.1971,388.1896,198.0571,389.2236,
        199.8031C391.1926,203.1301,392.8856,206.5791,394.8026,
        209.9321C395.5786,211.2911,399.8116,221.1531,402.4606,
        219.6241C406.9716,217.0201,394.9316,169.5711,378.7446,
        178.9181C377.2986,179.7521,375.0536,180.2861,374.4746,182.0371z" 
      Height="42.568" Canvas.Left="90.749" 
      StrokeStartLineCap="Flat" Stretch="Fill" 
      StrokeEndLineCap="Flat" Stroke="#FF231F20" 
      StrokeThickness="0.484" StrokeMiterLimit="4" 
      StrokeLineJoin="Miter" Canvas.Top="1.925" 
      Width="29.558"/>
    <Path Data="F1M404.306,217.707C407.38,209.691,417.496,
            204.789,425.95,205.555L425.95,205.555C437.2,206.569,
            454.855,198.851,452.374,184.103L452.374,184.103C451.374,
            178.159,447.041,175.532,441.349,175.534L441.349,
            175.534C426.333,175.536,401.876,193.818,404.306,217.707" 
        Height="42.173" Canvas.Left="120.786" 
        Stretch="Fill" Canvas.Top="0" Width="48.472">
          <Path.Fill>
             <RadialGradientBrush Center="0.505,0.34" 
               GradientOrigin="0.657,0.219" 
               RadiusY="-0.653" RadiusX="-0.568">
                  <GradientStop Color="#FFC7C923" Offset="0"/>
                  <GradientStop Color="#FF8B7E14" Offset="1"/>
             </RadialGradientBrush>
          </Path.Fill>
   </Path>
       <Path Data="M404.3057,217.7065C400.9537,184.7615,448.7357,
                     162.4805,452.3737,184.1025C454.8547,198.8515,
                     437.2007,206.5685,425.9507,205.5545C417.4957,204.7895,
                     407.3807,209.6915,404.3057,217.7065z" 
                Height="42.657" Canvas.Left="120.544" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF231F20" 
                StrokeThickness="0.484" StrokeMiterLimit="4" 
                StrokeLineJoin="Miter" Canvas.Top="-0.242" 
                Width="48.956"/>
       <Path Data="M405.3633,213.7773C410.4833,197.0653,428.4073,
                     186.0543,445.6303,187.5053C446.3673,187.3603,
                     447.1333,187.4273,447.9033,187.6023" 
                Height="26.884" Canvas.Left="121.77" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF696A6C" 
                StrokeThickness="0.484" StrokeMiterLimit="4"
                StrokeLineJoin="Miter" Canvas.Top="11.602" 
                Width="43.024"/>
       <Path Data="M411.5537,202.1333C413.5587,198.2793,415.6577,
                     194.3313,417.7447,190.4843" 
                Height="12.133" Canvas.Left="127.96" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF696A6C" 
                StrokeThickness="0.484" StrokeMiterLimit="4" 
                StrokeLineJoin="Miter" Canvas.Top="14.709" 
                Width="6.675"/>
       <Path Data="M421.9453,193.3672C423.5163,189.2672,
                      425.9853,185.3902,428.9773,182.3852" 
                Height="11.466" Canvas.Left="138.352" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF696A6C" 
                StrokeThickness="0.484" StrokeMiterLimit="4" 
                StrokeLineJoin="Miter" Canvas.Top="6.61" 
                Width="7.516"/>
       <Path Data="M433.292,188.6606C436.084,185.3616,
                      439.27,182.2546,442.592,179.6016" 
                Height="9.543" Canvas.Left="149.698" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF696A6C" 
                StrokeThickness="0.484" StrokeMiterLimit="4" 
                StrokeLineJoin="Miter" Canvas.Top="3.826" 
                Width="9.784"/>
       <Path Data="M412.6387,200.8149C416.3847,198.8229,420.7387,
                      198.9059,424.1097,201.1119" 
                Height="2.21" Canvas.Left="129.045" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF696A6C" 
                StrokeThickness="0.484" StrokeMiterLimit="4" 
                StrokeLineJoin="Miter" Canvas.Top="23.61" 
                Width="11.955"/>
       <Path Data="M422.8809,192.5947C427.4629,190.5367,
                      432.1079,191.6157,435.7489,195.3117" 
                Height="4.233" Canvas.Left="139.287" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF696A6C" 
                StrokeThickness="0.484" StrokeMiterLimit="4" 
                StrokeLineJoin="Miter" Canvas.Top="15.787" 
                Width="13.352"/>
       <Path Data="M436.2148,188.1265C440.3188,188.9795,
                      444.2928,191.0945,447.2158,193.9955" 
                Height="6.353" Canvas.Left="152.621" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF696A6C" 
                StrokeThickness="0.484" StrokeMiterLimit="4" 
                StrokeLineJoin="Miter" Canvas.Top="12.351" 
                Width="11.485"/>
       <Path Data="M441.377,264.6914L501.314,218.8584" 
                Height="48.833" Canvas.Left="156.525" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF231F20" 
                StrokeThickness="3" StrokeMiterLimit="4" 
                StrokeLineJoin="Miter" Canvas.Top="41.825" 
                Width="62.937"/>
       <Path Data="M517.5771,206.4209L501.8181,233.3119L500.0971,
                      219.7879L487.4971,214.5849L517.5771,206.4209z" 
                Fill="#FF231F20" Height="27.891" 
                Canvas.Left="203.645" StrokeStartLineCap="Flat" 
                Stretch="Fill" StrokeEndLineCap="Flat" 
                Stroke="#FF231F20" StrokeThickness="1" 
                StrokeMiterLimit="4" StrokeLineJoin="Miter" 
                Canvas.Top="30.387" Width="31.08"/>
       <Path Data="F1M325.727,230.356C336.728,224.856,343.94,
                      231.892,337.402,241.917L337.402,241.917C349.17,
                      239.302,349.074,251.2,343.324,256.7L343.324,
                      256.7C370.092,279.401,341.761,307.732,325.198,
                      297.916L325.198,297.916C329.121,309.475,314.163,
                      314.461,306.04,304.955L306.04,304.955C306.04,328.955,
                      323.959,337.931,333.224,362.145L333.224,362.145C343.284,
                      388.44,381.283,394.823,397.783,380.823L397.783,
                      380.823C422.676,393.95,457.7,387.539,469.596,
                      356.035L469.596,356.035C483.093,320.289,
                      506.383,291.69,499.227,264.856L499.227,
                      264.856C491.227,234.856,471.227,190.856,400.728,
                      215.356L400.728,215.356C387.198,210.007,375.898,
                      207.777,366.402,207.777L366.402,207.777C345.72,
                      207.777,333.609,218.362,325.727,230.356" 
                Height="180.277" Canvas.Left="22.688" 
                Stretch="Fill" Canvas.Top="32.243" 
                Width="194.523">
          <Path.Fill>
             <RadialGradientBrush Center="0.674,0.261" 
               GradientOrigin="0.674,0.261" 
               RadiusY="-0.408" RadiusX="-0.378">
                 <GradientStop Color="#FFDF785E" Offset="0"/>
                 <GradientStop 
                    Color="sc#1, 0.6877536, 0.101908535, 0.0670531541" 
                    Offset="0.73030436038970947"/>
                 <GradientStop Color="#FFD12229" 
                    Offset="1"/>
             </RadialGradientBrush>
          </Path.Fill>
       </Path>
       <Path Data="M499.2275,264.856C506.3825,291.69,483.0925,320.289,
                      469.5955,356.035C457.7005,387.539,422.6755,393.95,
                      397.7835,380.823C381.2835,394.823,343.2845,388.439,
                      333.2245,362.146C323.9585,337.931,306.0405,328.955,
                      306.0405,304.955C314.1635,314.461,329.1215,309.475,
                      325.1985,297.916C341.7605,307.732,370.0915,279.401,
                      343.3235,256.7C349.0735,251.2,349.1705,239.301,337.4025,
                      241.917C343.9405,231.892,336.7275,224.856,325.7275,
                      230.356C337.2275,212.856,357.7275,198.356,400.7275,
                      215.356C471.2275,190.856,491.2275,234.856,499.2275,
                      264.856z" 
                Height="181.277" Canvas.Left="22.189" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF5D5E60" 
                StrokeThickness="1" StrokeMiterLimit="4" 
                StrokeLineJoin="Miter" Canvas.Top="31.743" 
                Width="195.522"/>
       <Path Data="M348.7686,327.2012C369.3546,321.7742,365.0376,
                      343.4692,365.0376,343.4692" 
                Height="18.139" Canvas.Left="64.917" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF231F20" 
                StrokeThickness="1" StrokeMiterLimit="4" 
                StrokeLineJoin="Miter" Canvas.Top="150.296" 
                Width="17.646"/>
       <Path Data="M316.7446,364.0381L362.4076,329.1181" 
                Height="37.92" Canvas.Left="31.893" 
                StrokeStartLineCap="Flat" Stretch="Fill" 
                StrokeEndLineCap="Flat" Stroke="#FF231F20" 
                StrokeThickness="3" StrokeMiterLimit="4" 
                StrokeLineJoin="Miter" Canvas.Top="152.085" 
                Width="48.663"/>
       <Path Data="M303.4497,361.2314L304.1217,361.3734L315.8637,
                      362.8864L295.8837,378.1654L283.3517,
                      376.6004L303.4497,361.2314z" 
                Fill="#FF231F20" Height="17.934" 
                Canvas.Left="-0.5" StrokeStartLineCap="Flat" 
                Stretch="Fill" StrokeEndLineCap="Flat" 
                Stroke="#FF231F20" StrokeThickness="1" 
                StrokeMiterLimit="4" StrokeLineJoin="Miter" 
                Canvas.Top="185.198" Width="33.512"/>
       <Path Data="M295.7378,392.7979L297.6918,380.5289L317.6728,
                      365.2509C316.5628,369.1899,315.9618,373.3039,
                      315.7778,377.4739L295.7378,392.7979z" 
                Fill="#FF231F20" Height="28.547" 
                Canvas.Left="11.886" StrokeStartLineCap="Flat" 
                Stretch="Fill" StrokeEndLineCap="Flat" 
                Stroke="#FF231F20" StrokeThickness="1" 
                StrokeMiterLimit="4" StrokeLineJoin="Miter" 
                Canvas.Top="189.217" Width="22.935"/>
    </Canvas>
  </Canvas>
</Grid>
</Window>

将此 XAML 复制并粘贴到 Visual Studio IDE 的 XAML 代码窗口中。这是您得到的结果

apple.JPG

参考文献

  • MSDN 库
  • Deitel Associates
© . All rights reserved.