经过WPF绘制的图形都是矢量图,能够经过Design或Blend工具绘制原型图而后导出XAML再在Visual Studio中调整。绘图能够在任意布局控件中完成,经常使用的为Canvas和Grid,WPF会自动根据容器的不一样计算图形坐标。WPF基本图像都继承自Shape类。工具
Line,绘制直线,经过设置起始点坐标和终止点坐标肯定直线的位置,能够设置直线的样式,颜色,粗细等。经过设置Stroke属性设置图形的颜色,Stroke属性为Brush类型,Brush为抽象类。WPF系统包含丰富的Brush子类,SolidColorBrush,LinearGradientBrush(线性渐变画刷),RadialGradientBrush(径向渐变画刷),ImageBrush(图像填充),DrawingBrush(使用矢量图和位图做为填充),VisualBrush,使用可视化元素填充,能够当作可视化元素的截图。布局
Rectangle,绘制矩形,能够设置边框颜色,边框大小和填充,填充Fill同Stroke同样也为Brush类型。性能
Ellipse,绘制椭圆,使用方法与矩形没有什么区别,当width和height相同时即为正圆。动画
Path,路径是WPF绘图中最强大的工具,它便可以替代其余几种图形,也能够造成更复杂的图形。路径的重要属性是Data,经过设置Data来肯定具体的图形。Data的类型为Geometry,同Brush同样,Geometry为抽象类,WPF已经准备了若干继承类,包括LineGeometry,RectangleGeometry,EllipseGeometry,PathGeometry,StreamGeometry(轻量级PathGeometry),CombinedGeometry,GeometryGroup。Geometry类与Shape类不一样,Geometry不能做为单独元素使用,只能依附在其余图形上。PathGeometry能够绘制复杂的几何图形,其Figures能够容纳多个PathFigure对象,而PathFigure的Segments属性能够容纳多个PathSegment对象,经过PathSegment组合成复杂图形。一样的PathSegment为抽象类,继承类包括LineSegment,ArcSegment,BezierSegment,QuadraticBezierSegment,PolyBezierSegment,PolyQuadraticBezierSegment。全部这些Segment都没有起点,起点就是上一个Segment的终点,第一个Segment的起点为PathFigure的StartPoint。Path的示例代码:this
<Path Stroke="Blue"> <Path.Data> <PathGeometry> <PathFigure StartPoint="0,0"> <LineSegment Point="0,10"></LineSegment> <LineSegment Point="10,50"></LineSegment> <LineSegment Point="20,40"></LineSegment> <ArcSegment Point="40,80" Size="25,50"></ArcSegment> <BezierSegment Point1="20,20" Point2="30,30" Point3="40,40"></BezierSegment> </PathFigure> </PathGeometry> </Path.Data> </Path>
GeometryGroup也是Geometry的一个继承类,它最大的特色是能够将一组Geometry组合到一块儿。spa
Path如此强大,可使咱们为所欲为的绘制图形,但其缺点也不容忽视,就是其标签语法国语繁琐,若是图形过于复杂则会生成大量标签。经过使用路径标记语法能够极大的简化Path的描述,路径标记语法实际上就是各类线段的简记法,好比<LineSegment Point="10,50"></LineSegment>能够简记为L 10,50。使用路径标记语法通常分三步:移动至起点,绘图,闭合图形。路径标记语法不区分大小写,使用两个double表示一个点,中间用逗号或空格分隔,为避免混淆,常使用逗号分隔。插件
能够经过设置UIElement的Clip属性对控件进行裁剪,Clip类型即为Geometry。code
UIElement中BitmapEffect和Effect的两个属性用来给元素添加效果,BitmapEffect使用CPU计算资源,如今已经被遗弃。Effect属性使用GPU资源。BitmapEffect简单易用,它的类型为BitmapEffect类,是一个抽象类,WPF为咱们实现了若干子类,经过设置这些子类的属性来调整效果。示例代码:orm
<Button Width="120" Height="30"> <Button.BitmapEffect> <DropShadowBitmapEffect ShadowDepth="5" Opacity="0.7" Direction="-45"></DropShadowBitmapEffect> </Button.BitmapEffect> </Button>
Effect属性的类型为Effect,一样为抽象类,WPF为咱们实现了3个子类,BlurEffect,用来实现模糊效果。DropShadowEffect,用来实现投影效果。ShaderEffect,着色器效果,抽象类,它是留给滤镜插件开发人员的抽象接口。对象
控制变形的属性有两个RenderTransform和LayoutTransform,他们的数据类型都是Transform抽象类。Transform抽象类的派生类有以下一些,MatrixTransform,RotateTransform,ScaleTransform,SkewTransform,TranslateTransform,TransformGroup。呈现变形(RenderTransform)只改变元素的呈现位置,不会对布局系统形成影响,以减小资源占用,当使用动画时必定要使用呈现变形。注意控件呈如今哪里就在哪里提供交互。示例代码:
<Button Width="120" Height="30" Click="Button_Click"> <Button.RenderTransform> <TranslateTransform X="50" Y="50"></TranslateTransform> </Button.RenderTransform> </Button>
布局变形(LayoutTransform)会影响窗体的布局,致使布局从新计算,这会影响程序性能,所以布局变形只用在静态变形上,不会用于动画。
能够用来制做动画的属性必定是依赖属性,动画的基类为Timeline。简单动画由一个元素就能够完成,简单动画使用AnimationTimeline实现。复杂动画由多个元素和多个动画协同完成,复杂动画使用StoryBoard实现。
经过AnimationTimeline能够针对一个UI元素实现简单动画,AnimationTimeline为抽象类,WPF动画系统实现了经常使用数据类型的子类,如DoubleAnimationBase、ByteAnimationBase等。这种数据类型并以Base作后缀的类为抽象基类,每种数据类型的抽象基类又派生出3种具体动画,分别为简单动画、关键帧动画、沿路径运动的动画。注意并非全部的数据类型都能派生出这3种类型的动画。DoubleAnimationBase派生出DoubleAnimation(简单动画),DoubleAnimationUsingKeyFrames(关键帧动画),DoubleAnimationUsingPath(沿路径运动动画)。简单动画由变化时间Duration、变化起点From、变化幅度By、变化终点To四要素构成,若是同时设置To和By,By将被忽略。示例代码:
<Button x:Name="button" Width="120" Height="30" Click="Button_Click"> <Button.BitmapEffect> <DropShadowBitmapEffect ShadowDepth="5" Opacity="0.7" Direction="-45"></DropShadowBitmapEffect> </Button.BitmapEffect> <Button.RenderTransform> <TranslateTransform X="0" Y="0"></TranslateTransform> </Button.RenderTransform> </Button> private void Button_Click(object sender, RoutedEventArgs e) { DoubleAnimation dax = new DoubleAnimation(); DoubleAnimation day = new DoubleAnimation(); dax.From = 0; day.From = 0; dax.By = 100; day.By = 100; dax.Duration = new Duration(TimeSpan.FromMilliseconds(500)); day.Duration = new Duration(TimeSpan.FromMilliseconds(500)); button.RenderTransform.BeginAnimation(TranslateTransform.XProperty, dax); button.RenderTransform.BeginAnimation(TranslateTransform.YProperty, day); }
经过设置动画的高级控制属性能够是动画效果更逼真,如设置加速度、减速度、循环模式,渐进式缓冲等。
经过定义关键帧控制动画的执行效果,每一个帧都包含帧所在的时间和值,关键帧动画至少包含一个帧做为动画的结束位置。关键帧动画包含KeyFrames属性用来包含关键帧,能够向其中添加不一样类型的关键帧,最简单的关键帧为LinearDoubleKeyFrame。示例代码:
<Button x:Name="button" Width="120" Click="button_Click" HorizontalAlignment="Left"> <Button.RenderTransform> <TranslateTransform X="0" Y="0"></TranslateTransform> </Button.RenderTransform> Button</Button> private void button_Click(object sender, RoutedEventArgs e) { DoubleAnimationUsingKeyFrames dakf = new DoubleAnimationUsingKeyFrames(); dakf.Duration = new Duration(TimeSpan.FromSeconds(1)); LinearDoubleKeyFrame kf1 = new LinearDoubleKeyFrame(); kf1.KeyTime = KeyTime.FromPercent(0.2); kf1.Value = 50; LinearDoubleKeyFrame kf2 = new LinearDoubleKeyFrame(); kf2.KeyTime = KeyTime.FromPercent(0.4); kf2.Value = 100; LinearDoubleKeyFrame kf3 = new LinearDoubleKeyFrame(); kf3.KeyTime = KeyTime.FromPercent(0.8); kf3.Value = 150; dakf.KeyFrames.Add(kf1); dakf.KeyFrames.Add(kf2); dakf.KeyFrames.Add(kf3); button.RenderTransform.BeginAnimation(TranslateTransform.XProperty, dakf); }
控制动画沿指定路径移动,路径动画的Source属性用来控制关注路径的X轴的变化仍是Y轴的变化仍是曲线切线方向变化。示例代码:
<Grid x:Name="layoutRoot"> <Grid.Resources> <PathGeometry x:Key="path" Figures="M 0,150 C300,-100 300,400 600,120"></PathGeometry> </Grid.Resources> <Button x:Name="button" HorizontalAlignment="Left" VerticalAlignment="Top" Height="20" Click="button_Click"> <Button.RenderTransform> <TranslateTransform X="0" Y="0"></TranslateTransform> </Button.RenderTransform> Button</Button> </Grid> private void button_Click(object sender, RoutedEventArgs e) { PathGeometry path = layoutRoot.FindResource("path") as PathGeometry; DoubleAnimationUsingPath daupx = new DoubleAnimationUsingPath(); DoubleAnimationUsingPath daupy = new DoubleAnimationUsingPath(); daupx.Duration = new Duration(TimeSpan.FromSeconds(1)); daupx.PathGeometry = path; daupx.Source = PathAnimationSource.X; daupy.Duration = new Duration(TimeSpan.FromSeconds(1)); daupy.PathGeometry = path; daupy.Source = PathAnimationSource.Y; button.RenderTransform.BeginAnimation(TranslateTransform.XProperty, daupx); button.RenderTransform.BeginAnimation(TranslateTransform.YProperty, daupy); }
场景就是并行执行的一组动画,XAML代码示例:
<Grid> <Button VerticalAlignment="Top" HorizontalAlignment="Left"> <Button.RenderTransform> <TranslateTransform x:Name="tt" X="0" Y="0"></TranslateTransform> </Button.RenderTransform> <Button.Triggers> <EventTrigger RoutedEvent="Button.Loaded"> <BeginStoryboard> <Storyboard Duration="0:0:1"> <DoubleAnimation Duration="0:0:1" To="200" Storyboard.TargetName="tt" Storyboard.TargetProperty="X"></DoubleAnimation> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> Button</Button> </Grid>
C#代码示例:
<Grid> <Button VerticalAlignment="Top" HorizontalAlignment="Left" Click="Button_Click"> <Button.RenderTransform> <TranslateTransform x:Name="tt" X="0" Y="0"></TranslateTransform> </Button.RenderTransform> Button</Button> </Grid> private void Button_Click(object sender, RoutedEventArgs e) { DoubleAnimation da = new DoubleAnimation(); da.To = 200; da.Duration = new Duration(TimeSpan.FromSeconds(1)); Storyboard sb = new Storyboard(); sb.Duration = new Duration(TimeSpan.FromSeconds(1)); Storyboard.SetTargetName(da, "tt"); Storyboard.SetTargetProperty(da, new PropertyPath(TranslateTransform.XProperty)); sb.Children.Add(da); sb.RepeatBehavior = RepeatBehavior.Forever; sb.Begin(this); }