博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
精通C#---WPF图形呈现服务
阅读量:731 次
发布时间:2019-03-21

本文共 10313 字,大约阅读时间需要 34 分钟。

1.理解WPF的图形呈现服务

WPF采用的图形呈现方式:保留模式图形。
呈现图形数据时,即使图形被隐藏,它也总是存在的。

2.WPF图形呈现方式

2.1.形状:System.Windows.Shapes。
适合:交互图形
绘图和几何图形:System.Windows.Media.Drawing
适合:非交互,矢量,复杂。
可视化:System.Windows.Media.Visual
适合:大量图形

3.使用形状呈现图形

ShapeDefiningGeometryFillGeometryTransformStretchStrokeStrokeDashArray, StrokeEndLineCap, StrokeStartLineCap, StrokeThickness

4.Path

System.Windows.Media.Geometry:Bounds	//包含几何图形的边界矩形FillContains //判断给定Point(或其它Geometry对象)是否包含在指定Geometry派生类的边界内。GetArea		//返回Geometry派生类所占的整个区域GetRenderBounds //返回一个Rect,用来呈现Geometry派生类的最小矩形Tranform //设置一个用来改变几何图形呈现的Transform对象。

Geometry派生类类似Shape派生类。

Geometry派生类不知道如何直接呈现它们本身。
Geometry派生类所表示的只不过是点数据的集合。
Path并不是WPF中唯一使用集合图形集合的类。

Geometry派生类LineGeometry // RectangleGeometry //EllipseGeometryGeometryGroupCombinedGeometryPathGeometry

无论是在XAML还是在代码中,PathGeometry都是最难配置的。

PathGeometry中的每个段都是由包含其它段和图像的对象组成的。如:ArcSegment,BezierSegment,LineSegment,PolyBezierSegment,PolyLineSegment,PolyQuadraticBezierSegment等。

PathGeometry支持迷你语言配置,来简化XAML内容。// Path Markup Syntax

5.WPF画刷和画笔

WPF画刷派生类:
DrawingBrush // 使用Drawing派生对象[GeometryDrawing, ImageDrawing, VideoDrawing]绘制区域。
ImageBrush // 使用图像绘制区域
LinearGradientBrush // 使用线性渐变绘制区域
RadialGradientBrush // 使用径向渐变绘制区域
SolidColorBrush // 绘制纯色,设置其Color属性
VisualBrush // 使用Visual派生对象[DrawingVisual, Viewport3DVisual, ContainerVisual]绘制区域。

6.配置画笔

7.图形变换

System.Windows.Media.Transform

MatrixTransform // 创建任意一个矩阵变换,用于操作2D平面的对象或坐标系RotateTransform // 在2D(x,y)坐标系内围绕一个指定点,按顺时针方向旋转对象ScaleTransform // 在2D(x, y)坐标系内缩放一个对象SkewTransform // 在2D(x, y)坐标系内扭曲一个对象TranslateTransform // 在2D(x, y) 坐标系内平移(移动)一个对象TransformGroup // 标识由其它Transform对象组合成的复合Transform

可以对任何UIElement应用变换。

LayoutTransform属性用于将元素呈现到布局管理器之前发生变换。
RenderTransform发生于元素呈现在容器中后。
变换可以对单个项,也可以对一个布局管理器。

VS属性选项卡的变换类型:

Translate // 平移
Rotate // 旋转
Scale // 缩放
Skew // 扭曲
Center Point // 中心点
Flip // 翻转

8.使用绘图和几何图形呈现图形数据

Shape类具有丰富的继承链,为此也需耗费较大内存。Drawing要精简很多。
// System.Windows.Media.Drawing
WPF提供了很多Drawing的扩展类:
DrawingGroup // 多个独立的Drawing派生对象合并成一个单独的复合绘图呈现。
GeometryDrawing // 用轻量级方式呈现2D
GlyphRunDrawing // 用WPF图形呈现服务呈现文本。
ImageDrawing // 在矩形边界内呈现图像文件或几何图形集
VideoDrawing // 播放音频或视频。

Drawing没有继承UIElement,因此不能呈现。

要想显示它们的内容,只能将它们放置到一个宿主对象中。如:DrawingImage,DrawingBrush,DrawingVisual。

DrawingImage将绘图和几何图形放置到WPF的Image控件。

DrawingBrush可用来构建一个基于绘图和几何图形的画刷。
DrawingVisual仅用于图形呈现的完全由C#代码驱动的“可视化”层。

9.DrawingBrush

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;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 RenderingWithShapes{ /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { private enum SelectedShape { Circle, Rectangle, Line } private SelectedShape currentShape; private bool isFlipped = false; public MainWindow() { InitializeComponent(); } private void rectOption_Click(object sender, RoutedEventArgs e) { currentShape = SelectedShape.Rectangle; } private void circOption_Click(object sender, RoutedEventArgs e) { currentShape = SelectedShape.Circle; } private void lineOption_Click(object sender, RoutedEventArgs e) { currentShape = SelectedShape.Line; } private void canvasDrawingArea_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Shape shapeToRender = null; switch(currentShape) { case SelectedShape.Circle: { shapeToRender = new Ellipse() { Height = 35, Width = 35 }; RadialGradientBrush brush = new RadialGradientBrush(); brush.GradientStops.Add(new GradientStop((Color)ColorConverter.ConvertFromString("#FF87E71B"), 0.589)); brush.GradientStops.Add(new GradientStop((Color)ColorConverter.ConvertFromString("#FF2BA92B"), 0.013)); brush.GradientStops.Add(new GradientStop((Color)ColorConverter.ConvertFromString("#FF34B71B"), 1)); shapeToRender.Fill = brush; } break; case SelectedShape.Rectangle: { shapeToRender = new Rectangle() { Fill = Brushes.Red, Height = 35, Width = 35, RadiusX = 10, RadiusY = 10 }; } break; case SelectedShape.Line: { shapeToRender = new Line { Stroke = Brushes.Blue, StrokeThickness = 10, X1 = 0, X2 = 50, Y1 = 0, Y2 = 50, StrokeStartLineCap = PenLineCap.Triangle, StrokeEndLineCap = PenLineCap.Round }; } break; default: return; } if (isFlipped) { RotateTransform rotate = new RotateTransform(-180); shapeToRender.RenderTransform = rotate; } Canvas.SetLeft(shapeToRender, e.GetPosition(canvasDrawingArea).X); Canvas.SetTop(shapeToRender, e.GetPosition(canvasDrawingArea).Y); canvasDrawingArea.Children.Add(shapeToRender); } private void canvasDrawingArea_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { Point pt = e.GetPosition((Canvas)sender); HitTestResult result = VisualTreeHelper.HitTest(canvasDrawingArea, pt); if(result != null) { canvasDrawingArea.Children.Remove(result.VisualHit as Shape); } } private void flipCanvas_Click(object sender, RoutedEventArgs e) { if (flipCanvas.IsChecked == true) { RotateTransform rotate = new RotateTransform(-180); canvasDrawingArea.LayoutTransform = rotate; isFlipped = true; } else { canvasDrawingArea.LayoutTransform = null; isFlipped = false; } } private void btnSkew_Click(object sender, RoutedEventArgs e) { myCanvas.LayoutTransform = new ScaleTransform(-1, 1); } private void btnRotate_Click(object sender, RoutedEventArgs e) { myCanvas.LayoutTransform = new RotateTransform(180); } private void btnFile_Click(object sender, RoutedEventArgs e) { myCanvas.LayoutTransform = new SkewTransform(40, -20); } }}

10.DrawingImage

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;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 WpfApplication3{ /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void LeftEye_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { LeftEye.Fill = new SolidColorBrush(Colors.Red); } private void RightEar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { System.Windows.Media.Effects.BlurEffect blur = new System.Windows.Media.Effects.BlurEffect(); blur.Radius = 10; RightEar.Effect = blur; } }}

11.使用可视化层呈现图形数据

System.Windows.Media.Visual
派生类:
DrawingVisual
Viewport3DVisual
ContainerVisual

12.DrawingVisual

使用DrawingVisual在平面呈现数据步骤。
从DrawingVisual获取DrawingContext对象
使用DrawingContext呈现图形数据

//

更新所呈现容器中的逻辑树和可视化树
重写FrameworkElement的两个虚方法,允许容器获取你创建的可视化数据。

转载地址:http://ngmgz.baihongyu.com/

你可能感兴趣的文章