您的位置:首页 > 其它

WPF的基础知识

2013-10-11 20:50 429 查看
一个WPF应用程序从两个线程开始,分别负责用户界面(UI)的管理和渲染。托管代码为用户提供构建WPF所需要的各种功能,如布局和绑定等,通常用户界面管理线程使用该部分代码;非托管代码主要负责图形的叠加显示和渲染,那么使用该部分代码的是不能被用户接触的渲染线程,两个线程之间通过消息来传递数据。。

WPF的全称是Windows Presentation Foundation,意思是Windows描述语言。它的一个主要特性是设计人员和开发人员的工作很容易分开,设计人员的工作成果可以直接供开发人员使用。为此,必须理解XAML。WPF在建立应用程序时使用XAML。XAML表示可扩展的应用程序标记语言,Extensible Application Markup Lanuage。XAML是用于创建窗体的XML声明,它代表WPF应用程序的所有可视化部分和操作。虽然只可以编程利用WPF应用程序,但WPF是面向声明性编程的第一步,而声明性编程是编程业的趋势。声明性编程是指,不是利用编程语言,如C#、VB或Java,通过编程来创建对象,而是通过XML类型的编程来声明所有元素。

形状是WPF的核心元素。利用形状,可以绘制矩形、线条、椭圆、路径、多边形和折线等二维图形,这些图形用派生自抽象类Shape的类表示。下图描述了System.Windows.Shapes 名称空间中可用的图形:

Shape类说明
Line可以在坐标(X1,Y1)到(X2,Y2)之间绘制一条线
Rectangle使用Rectangle类,通过指定Width和Hieght可以绘制一个矩形
Ellipse使用Ellipse类,可以绘制一个椭圆
Path使用Path类可以绘制一系列直线和曲线。Data属性是Geometry类型。还可以使用派生自基类Geometry的类绘制图形,或使用路径标记语法来定义图形。
Polygon使用Polygon类可以绘制由线段连接而成的封闭图形。多边形由一系列赋予Points属性的Point对象定义
Polyline类似于Polygon类,使用Polyline也可以绘制连接起来的线段。与多边形的区别是折线不一定是封闭图形。
下面的XAML代码示例绘制了一个黄色笑脸,它用一个椭圆表示笑脸,两个椭圆表示眼睛,两个椭圆表示眼睛中的瞳孔,一条路径表示嘴型:

<Window x:Class="ShapesDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Canvas>

<Ellipse Canvas.Left="10" Canvas.Top="10" Width="100" Height="100" Stroke="Blue" StrokeThickness="4" Fill="Yellow" />
<Ellipse Canvas.Left="30" Canvas.Top="12" Width="60" Height="30" >
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0.1" Color="DarkGreen"/>
<GradientStop Offset="0.7" Color="Transparent"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Canvas.Left="30" Canvas.Top="35" Width="25" Height="20" Stroke="Blue" StrokeThickness="3" Fill="White"/>
<Ellipse Canvas.Left="40" Canvas.Top="43" Width="6" Height="5" Fill="Black"/>
<Ellipse Canvas.Left="65" Canvas.Top="35" Width="25" Height="20" Stroke="Blue" StrokeThickness="3" Fill="White"/>
<Ellipse Canvas.Left="75" Canvas.Top="43" Width="6" Height="5" Fill="Black"/>
<Path Name="mouth" Stroke="Blue" StrokeThickness="4" Data="M 40,74 Q 57,95 80,74"/>

</Canvas>

</Grid>
</Window>

上述代码描述出的图形如下:



因为WPF基于矢量,所以可以重置每个元素的大小。基于矢量的图形现在可以缩放、旋转和倾斜。我们可以给Canvas元素的LayoutTransform属性添加ScaleTransform元素来让整个画布的内容在X和Y上放大2倍。

<Canvas.LayoutTransform>
<ScaleTransform ScaleX="1.5" ScaleY="1.5"/>
</Canvas.LayoutTransform>

旋转与绽放的执行方式相同,使用RotateTransform元素,可以定义旋转的角度(Angel属性是角度):
<Canvas.LayoutTransform>
<RotateTransform Angle="40"/>
</Canvas.LayoutTransform>

对于倾斜,我们可以使用SkewTransform元素,此时可以指定X和Y方向的倾斜角度:
<Canvas.LayoutTransform>
<SkewTransform AngleX="20" AngleY="25"/>
</Canvas.LayoutTransform>

为了同时执行旋转和倾斜操作,可以定义一个TransformGroup,它同时包含RotateTransform和SkewTransform,如下:
<Canvas.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="40"/>
<SkewTransform AngleX="20" AngleY="25"/>
</TransformGroup>
</Canvas.LayoutTransform>

我们也可以定义一个MatrixTransform,其中Matrix元素指定了用于拉伸的M11和M22属性,以及用于倾斜的M12和M21属性,如下:
<Canvas.LayoutTransform>
<MatrixTransform>
<MatrixTransform.Matrix>
<Matrix M11="0.8" M22="1.6" M12="1.3" M21="0.4"/>
</MatrixTransform.Matrix>
</MatrixTransform>
</Canvas.LayoutTransform>

下面为上述几种变换的结果图:











对于平滑的颜色变化,可以使用LinearGradientBrush。这个画笔定义了StartPoint和EndPoint属性。使用这些属性可以为线性渐变指定二维坐标。默认的渐变方向是从(0,0)到(1,1)的对角线。定义其他值可以给渐变指定不同的方向。例如,StartPoint指定为(0,0),EndPoint指定为(0,1),就得到了一个垂直渐变;StartPoint不变,EndPoint值指定为(1,0),就得到了一个水平渐变。通过该画笔的内容,可以用GradientStop元素定义指定偏移位置的颜色值。在各个偏移位置之间,颜色是平滑过渡的。

<Button Content="Solid Color" Margin="12,12,411,269" Width="80" Height="30">
<Button.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="LightGreen"/>
<GradientStop Offset="0.9" Color="Green"/>
<GradientStop Offset="1" Color="DarkGreen"/>
</LinearGradientBrush>
</Button.Background>
</Button>


使用RadialGradientBrush可以以放射方式产生平滑的颜色渐变,示例代码:

<Canvas Width="200" Margin="-1,135,304,21">
<Path Canvas.Left="20" Canvas.Top="30" Stroke="Black">
<Path.Fill>
<RadialGradientBrush GradientOrigin="0.2,0.2">
<GradientStop Offset="0" Color="LightBlue"/>
<GradientStop Offset="0.6" Color="Blue"/>
<GradientStop Offset="1.0" Color="DarkBlue"/>
</RadialGradientBrush>
</Path.Fill>
<Path.Data>
<CombinedGeometry GeometryCombineMode="Union">
<CombinedGeometry.Geometry1>
<EllipseGeometry Center="80,60" RadiusX="80" RadiusY="40"/>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<RectangleGeometry Rect="30,60 105 50"/>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
</Canvas>


DrawingBrush可以定义用画笔绘制的图形,用画笔绘制的图形在GeometryDrawing元素中定义:

<Button Content="Drawing Brush" Margin="-1,56,374,195" Padding="10" Width="130" Height="60">
<Button.Background>
<DrawingBrush>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Red">
<GeometryDrawing.Pen>
<Pen>
<Pen.Brush>
<SolidColorBrush>Blue</SolidColorBrush>
</Pen.Brush>
</Pen>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="70,40">
<PathFigure.Segments>
<BezierSegment Point1="90,37" Point2="130,46" Point3="150,63" />
<LineSegment Point="120,110"/>
<BezierSegment Point1="100,95" Point2="70,90" Point3="45,91"/>
<LineSegment Point="70,40"/>
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Button.Background>
</Button>


要把图像加载到画笔中,可以使用ImageBrush元素。通过这个元素,显示ImageSource属性定义的图像。图像可以从文件系统中访问,或者在程序集的资源中访问。下面的示例是从文件系统中访问:

<Button Content="Image Brush" Width="100" Height="80" Margin="241,12,162,219" Foreground="White">
<Button.Background>
<ImageBrush ImageSource="D:\vs.2010\WindowsPresentationFoundation\Brush\Image\1.png" />
</Button.Background>
</Button>

从文件系统中访问图像有危险,假如这条路径不存在该图像文件,那么就会造成程序报错。

VisualBrush可以在画笔中使用其他WPF元素。如下代码为一个Button元素中包含一个矩形和另一个按钮:

<Button Content="Visual Brush" Width="100" Height="80" Margin="135,12,268,219">
<Button.Background>
<VisualBrush>
<VisualBrush.Visual>
<StackPanel Background="White">
<Rectangle Width="25" Height="25" Fill="Blue"/>
<Button Content="Drawing Button" Background="Red" />
</StackPanel>
</VisualBrush.Visual>
</VisualBrush>
</Button.Background>
</Button>

我们可以给VisualBrush添加任意UIElement,还可以创建反射等有趣的结果。如下示例,在Button按钮里面利用VisualBrush添加一个MediaElement播放视频。并得到它的反射效果。
<Button Foreground="White" Margin="12,12,22,12">
<StackPanel>
<MediaElement x:Name="reflected" Source="D:\vs.2010\WindowsPresentationFoundation\Brush\Image\爱情惹的祸.mp4" Width="324" Height="122" />
<Border Height="100" >
<Rectangle Height="125" Width="332">
<Rectangle.Fill>
<VisualBrush Opacity="0.35" Stretch="None" Visual="{Binding ElementName=reflected}">
<VisualBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="-1"/>
<TranslateTransform Y="1"/>
</TransformGroup>
</VisualBrush.RelativeTransform>
</VisualBrush>
</Rectangle.Fill>
</Rectangle>
</Border>
</StackPanel>
</Button>


这里面显示的按钮包含一个StackPanel,它包含一个播放视频的MediaElement和一个Border。Border边框包含一个VisualBrush填充的矩形。这支画笔定义了一个不透明值和一个变换。把Visual属性绑定到Border元素上。变换通过设置VisualBrush的RelativeTransform属性来完成。这个变换使用了相对坐标。把ScaleY设置为-1,完成Y方向上的反射。TranslateTransform在Y方向上移动变换。从而使反射效果位于原始对象的下面。

下图为显示结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: