形状,画刷和变换
   概述:

在许多用户界面技术中,普通控件和自定义绘图之间具有清晰的区别。通常来说,绘图特性只用于特定的应用程序--如游戏,数据可视化和物理仿真等。而WPF具有一个非常不同的原则。它以相同的方式处理控件和绘制的图形。
 一.理解形状。
       在WPF用户界面中,绘制2D图形内容的最简单方法是使用形状(shape) :专门用于表示简单的直线,椭圆,矩形以及多边形的类。从技术角度讲,形状就是所谓的绘图图元。可以组合这些基本元素来创建更复杂的图形。形状最重要的细节是,它们都继承自FrameworkElement类。因此,形状是元素。这样会带来许多重要的结果:
     1.形状绘制自身。不需要管理无效的情况和绘图过程。如:当移动内容,改变窗口尺寸或改变形状属性时,不需要手动重新绘制形状。
    2.使用与其他元素相同的方式组织形状。换句话说,可在学过的任何布局容器中放置一个形状(尽管,Canvas明显是最有用的容器,因为它允许在特定的坐标位置放置形状,当构建复杂的具有多个部分的图画时,这是很重要的)。
     3.形状支持与其他元素相同的事件。这意味着为了处理焦点,按下键盘,移动鼠标以及单击鼠标等,不需要进行任何额外的工作。可以使用用于其他元素的相同的事件集,并且同样支持工具提示,上下文菜单和拖放操作。

二.Shape 类
     每个形状都继承自抽象的System.Windows.Shapes.Shape类。如下显示了形状类的继承层次。

如图 ,只有很少一部分类继承自Shape类。Line(直线),ellipse(椭圆),Rectangle(长方形,矩形),Polyline是一系列相互连接的直线,Polygon是由一系列相互连接的直线形成的闭合图形,最后Path类具有非常强大的功能,能够将多个基本形状组合成一个单独的元素。

<Window xmlns:my="clr-namespace:StudyWPF"  x:Class="StudyWPF.形状画刷"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="形状画刷" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0">
            <Line Stroke="Blue" X1="0" Y1="0" X2="300" Y2="50"></Line>
        </StackPanel>
        <Canvas Grid.Row="1">
            <Ellipse Fill="Tomato" Stroke="Blue" Height="50" Width="100" Margin="5" HorizontalAlignment="Left"></Ellipse>
            <Rectangle Fill="Bisque"  Stroke="Red" Height="50" RadiusX="20" RadiusY="20" Width="100" Margin="5" HorizontalAlignment="Left"></Rectangle>
            <Ellipse Fill="RoyalBlue" Stroke="Blue" Canvas.Left="100" Canvas.Top="50" Width="100" Height="50"></Ellipse>
            <Rectangle Fill="DeepSkyBlue" Stroke="Blue" Canvas.Left="30" Canvas.Top="40" Width="100" Height="50"></Rectangle>
           
        </Canvas>
    </Grid>
</Window>
Ellipse类没有增加任何属性。Rectangle类只增加了两个属性:RadiusX和RadiusY。如果将这两个属性的值设置成非零,就可以创建出优美的圆形拐角

三。形状的布局:

1.  形状位置 设置:通常不希望使用StackPanel,DockPanle以及WrapPanel面板,因为它们被设计为独立的元素,Grid面板更灵活一些,因为它允许在同一个单元格中放置任意多个元素(尽管不能在单元格中的不同部分定位矩形和椭圆)所以最理想的容器是Canvas,该容器要求使用Left,Top,Right或Bottom附加属性,为每个形状指定坐标。这样可以完全控制形状如何相互重叠;如果使用Canvas容器,标签的顺序是很重要的,在上面的示例中,矩形叠加在椭圆的上面,因为在标签列表中首先出现的是椭圆,所以首先绘制椭圆。
  并且:Canvas 容器不需要占据整个窗口。例如,完全可以创建一个Grid面板,并在Grid面板的一个单元格中使用Canvas容器。对于在一个动态的,可以自由流动的用户界面中锁定一小部分绘图逻辑,这是一种非常好的方法。

2.使用viewBox控件缩放形状:
        使用Canvas控件的唯一限制是图形不能改变自身的尺寸以适应更大或更小的窗口。对于按键这非常合理(在这些情况下,按钮不改变尺寸),但是对于其他类型的图形内容,情况就不同了。例如,可能创建一个希望可以改变大小的复杂图形,从而可以充分利用可用的空间。如果希望联合Canvas控件的精确控制功能和容易改变尺寸功能,可以使用Viewbox元素。用法如下: <Viewbox  HorizontalAlignment="Center" Width="45" Height="45" Grid.Row="3" Name="lblProgress" Grid.Column="2" Visibility="Collapsed">
                <Canvas RenderTransformOrigin="0.5,0.5"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    Width="120" Height="120" >
                    <Ellipse Width="21.835" Height="21.862"
                         Canvas.Left="20.1696"
                         Canvas.Top="9.76358"
                         Stretch="Fill" Fill="Orange"
                         Opacity="1.0"/>
                    <Ellipse Width="21.835" Height="21.862"
                         Canvas.Left="2.86816"
                         Canvas.Top="29.9581" Stretch="Fill"
                         Fill="Black" Opacity="0.9"/>
                    <Ellipse Width="21.835" Height="21.862"
                         Canvas.Left="5.03758e-006"
                         Canvas.Top="57.9341" Stretch="Fill"
                         Fill="Black" Opacity="0.8"/>
                    <Ellipse Width="21.835" Height="21.862"
                         Canvas.Left="12.1203"
                         Canvas.Top="83.3163" Stretch="Fill"
                         Fill="Black" Opacity="0.7"/>
                    <Ellipse Width="21.835" Height="21.862"
                         Canvas.Left="36.5459"
                         Canvas.Top="98.138" Stretch="Fill"
                         Fill="Black" Opacity="0.6"/>
                    <Ellipse Width="21.835" Height="21.862"
                         Canvas.Left="64.6723"
                         Canvas.Top="96.8411" Stretch="Fill"
                         Fill="Black" Opacity="0.5"/>
                    <Ellipse Width="21.835" Height="21.862"
                         Canvas.Left="87.6176"
                         Canvas.Top="81.2783" Stretch="Fill"
                         Fill="Black" Opacity="0.4"/>
                    <Ellipse Width="21.835" Height="21.862"
                         Canvas.Left="98.165"
                         Canvas.Top="54.414" Stretch="Fill"
                         Fill="Black" Opacity="0.3"/>
                    <Ellipse Width="21.835" Height="21.862"
                         Canvas.Left="92.9838"
                         Canvas.Top="26.9938" Stretch="Fill"
                         Fill="Black" Opacity="0.2"/>
                    <Ellipse Width="21.835" Height="21.862"
                         Canvas.Left="47.2783"
                         Canvas.Top="0.5" Stretch="Fill"
                         Fill="Black" Opacity="0.1"/>
                    <Canvas.RenderTransform>
                        <RotateTransform x:Name="SpinnerRotate"
                                     Angle="0" />
                    </Canvas.RenderTransform>
                    <Canvas.Triggers>
                        <EventTrigger RoutedEvent="ContentControl.Loaded">
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation
                                    Storyboard.TargetName
                                        ="SpinnerRotate"
                                     Storyboard.TargetProperty
                                        ="(RotateTransform.Angle)"
                                     From="0" To="360"
                                     Duration="0:0:01"
                                     RepeatBehavior="Forever" />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </Canvas.Triggers>

</Canvas>
            </Viewbox>

3 。 直线:Line形状表示连接一个点和另一个点的一条直线。起点和终点由4个属性设置:(X1,Y1) (X2,Y2)
对于直线,Fill属性不起作用,必须设置Stroke属性。在直线中使用的坐标是相对于放置直线的矩形的左上角的坐标(添加直线时会在容器中保留一块矩形空间用于放置直线,)

4 . 拆线:通过Polyline类可以绘制一系列相互连接的直线。只需要使用Points属性提供一系列X和Y坐标。从技术角度讲,Points属性需要一个PointCollection对象,但是在XAML中使用基于简单字符串的语法
<Polyline Stroke="Blue" StrokeThickness="5" Points="10,150 30,140 50,160 70,130 90,170 110,120 130,180 150,110 170,190 190,100 210,240"></Polyline>

WPF学习系列之八(形状,画刷和变换)的更多相关文章

  1. WPF 10天修炼 第八天 - 形状、画刷和变换

    图形 在WPF中使用绘图最简单的就是使用Shape类.Shape类继承自FrameworkElement,是一个专门用来绘图的类.Shape类中年派生的类有直线.矩形.多边形和圆形等. System. ...

  2. WPF学习系列 游戏-选张图片做成9宫格拼图

    今天要学习一个拼图项目. 目标是传入一张图片,然后将它分成9份,去掉一份,鼠标点击进行拼图. 源文件结构很简单 第一步.新建项目 这一步没什么好说的,新建一个项目就跟源文件结构一样了 第二步.页面布局 ...

  3. WPF学习系列之七 (样式与行为)

    样式(Styles)是组织和重用格式化选项的重要工具.不是使用重复的标记填充XAML,以设置诸如边距.颜色及字体等细节,而可以创建一系列封装所有这些细节的样式.然后可以在需要之处通过一个属性应用样式. ...

  4. Dubbo学习系列之八(分布式事务之MQ方案)

    自从小王玩起了微服务,发现微服务果然很强大,好处真是太多,心中暗喜,然而,却也遇到了分布式中最棘手的问题:分布式事务.小王遍访各路神仙,也无个完美开源解决方案,当然,也有些实际可行的手法,虽不算完美, ...

  5. WPF学习系列之五(WPF控件)

    控件:    1.内容控件------这些控件能够包含嵌套的元素,为它们提供几乎无限的显示能力.内容控件包括Lable,Button 以及ToolTip类. 内容控件是更特殊的控件类型,它们可以包含( ...

  6. WPF学习系列 简单的窗体设置

    今天要学习的源码是一个窗体设置.效果如下,可拖拽.这让我想起了vs的启动界面 下面是源码的情况 项目结构: 窗体代码: cs代码 1.新建项目 略 2.设置窗体 AllowsTransparency= ...

  7. WPF学习系列 绘制旋转的立方体

    我是一年经验的web程序员,想学习一下wpf,比较喜欢做项目来学习,所以在网上找了一些项目,分析代码,尽量能够做到自己重新敲出来 第一个项目是 中间的方块会不停的旋转. 第一步,新建wpf项目 第二步 ...

  8. Gradle学习系列之八——构建多个Project

    在本系列的上篇文章中,我们讲到了Gradle的依赖管理,在本篇文章中,我们将讲到如何构建多个Project. 请通过以下方式下载本系列文章的Github示例代码: git clone https:// ...

  9. WPF学习系列之六 (元素绑定)

    元素绑定 简单地说,数据绑定是一种关系,该关系告诉WPF从一个源对象提取一些信息,并使用这些信息设置目标对象的属性.目标属性总是依赖属性,并且通常位于WPF元素中. 一.将元素绑定到一起 <Wi ...

随机推荐

  1. duplicate symbols

    duplicate symbol _mCollecatView in: /Users/Rubert/Library/Developer/Xcode/DerivedData/ChengDuHidengD ...

  2. JMS的常用方法

    import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; impor ...

  3. OpenGL 开始学习指南

    近期需要做一个涌潮的预报与仿真模拟,为了使模型更具有真实感,且逼真,使用起来更灵活.感觉还是得从基础的OpenGL学习.鉴于Direct3D技术存在的众多不确定性,且评论不太好的原因,决定用OpenG ...

  4. phpStudy Linux安装集成环境 (CentOS--7)

    phpStudy for Linux (lnmp+lamp一键安装包) phpStudy for Linux 支持Apache/Nginx/Tengine/Lighttpd, 支持php5.2/5.3 ...

  5. Eclipse 中使用 ctrl 无法追踪函数的问题

    Eclipse 中使用 ctrl 无法追踪函数的问题 Eclipse 项目中应该有 .buildpath , .project 两个文件,如果 Eclipse 中使用 ctrl 无法追踪函数, 第一步 ...

  6. C Primer Plus(第五版)8

    第 8 章 字符输入/输出和输入确认 在本章中你将学习下列内容: · 有关输入,输出以及缓冲和非缓冲输入之间的区别的更多内容. · 从键盘模拟文件结尾条件的方法. · 如何重定向将你的程序与文件相连接 ...

  7. C Primer Plus(第五版)1

    这是C Primer Plus(第五版)的第一章,上传上来主要是方便我进行做笔记,写注释,还有我会删掉一些“废话”等. 1.1 C语言的起源 贝尔实验室的 Dennis Ritchie 在1972年开 ...

  8. HttpRequestValidationException (0x80004005) 的三种可能的解决方法

    从客户端中检测到有潜在危险的 Request.Form 值 从客户端(txtSupplement="<textarea name="cont...")中检测到有潜在 ...

  9. Chapter Schema

    Chapter Schema Schema是XF的核心,每一个读写方法都有一个相关联的Schema.方法首先解析Schema,然后再根据Schema的配置的执行. 那Schema是什么呢?Schema ...

  10. html5—— 应用程序缓存

    使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本. 什么是应用程序缓存(Application Cache)? HTML5 引入了应用程序缓存,这 ...