【WPF学习】第三十九章 理解形状

  在WPF用户界面中,绘制2D图形内容的最简单方法是使用形状(shape)——专门用于表示简单的直线、椭圆、矩形以及多变形的一些类。从技术角度看,形状就是所谓的绘图图元(primitive)。可组合这些基本元素来创建更复杂的图形。

  关于WPF中形状的重要细节是,它们都继承自FrameworkElement类。因此,形状是元素。这样会带来许多重要的结果:

  •   形状绘制自身。不需要管理无效的情况和绘图过程。例如,当移动内容、改变窗口尺寸或改变形状属性时,不需要手动重新绘制形状。
  •   使用与其他元素相同的方式组织形状。换句话说,可在前面学过的任何布局容器中放置形状(尽管Canvas明显是最有用的容器,因为它允许在特定的坐标位置放置形状,当构建复杂的具有多个部分的图画时,这很重要)。
  •   形状支持与其他元素相同的事件。这意味着为了处理焦点、按下键盘、移动鼠标以及单击鼠标等,不必执行任何额外工作。可使用用于其他元素的相同事件集,并同样支持工具提示、上下文菜单和拖放操作。

一、Shape类

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

 图 WPF形状类

  正如上面看到的,相对来说,只有很少一部分类继承自Shape类。Line、Ellipse以及Rectangle都很直观,Polyline是一系列相互连接的直线,Polygon是由一系列相互连接的直线形成的闭合图形。最后,Path类功能强大,能将多个基本形状组合成单独的元素。

  尽管Shape类自身不能执行任何工作,但它定义了少量的重要属性。下表列出了这些属性。

表 Shape类的属性

 二、矩形和椭圆

  矩形和椭圆是两个最简单的形状。为创建矩形或椭圆,需要设置大家熟悉的Height和Width属性(这两个属性继承自FrameworkElement类)来定义形状的尺寸,然后设置Fill或Stroke属性(或同时设置这两个属性)使形状可见。还可以使用MinHeigth、MinWidth、HorizontalAlignment、VerticalAlignment以及Margin等属性。

  下面举一个简单示例,该例在StackPanel面板上放置了一个椭圆和一个矩形,效果图如下所示:

<StackPanel>
            <Ellipse Fill="Yellow" Stroke="Blue" Height="50" Width="100" Margin="5" HorizontalAlignment="Left"></Ellipse>
            <Rectangle Fill="Yellow" Stroke="Blue" Height="50" Width="100" Margin="5" HorizontalAlignment="Left"></Rectangle>
</StackPanel>

   Ellipse类没有增加任何属性。Rectangle类只增加了两个属性:RadiusX和RadiusY。如果将这两个属性的值设为非零值,就可以创建出美观的圆形拐角。

  可认为RadiusX和RadiusY属性是用于填充矩形拐角的椭圆。例如,如果将这两个属性都设为10,WPF会使用10个单位宽的圆形边缘绘制拐角。随着半径的增大,矩形拐角的更多部分会被替换。如果增加RadiusY属性的值,使其大于RadiusX属性的值,矩形拐角的左边和右边会更平缓,而顶部和底边的边缘会更尖锐。如果增大RadiusX属性的值,使其等于矩形宽度,并增加RadiusY属性的值,使其等于矩形的宽度,矩形最后会变成普通的椭圆。如下图所示:

www.wityx.com www.wityx.com
<Window x:Class="Drawing.RoundedRectangles"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="RoundedRectangles" Height="447.744" Width="300">
    <StackPanel>
        <TextBlock Margin="5,5,0,0">Corner radius of 5.</TextBlock>
        <Rectangle Fill="Yellow" Stroke="Blue" RadiusX="5" RadiusY="5"
               Width="100" Height="60" Margin="5"  HorizontalAlignment="Left">
        </Rectangle>
        <TextBlock Margin="5,5,0,0">Corner radius of 10.</TextBlock>
        <Rectangle Fill="Yellow" Stroke="Blue" RadiusX="10" RadiusY="10"
               Width="100" Height="60" Margin="5"  HorizontalAlignment="Left"></Rectangle>
        <TextBlock Margin="5,5,0,0">Corner radius of 10 (X) and 25 (Y).</TextBlock>
        <Rectangle Fill="Yellow" Stroke="Blue" RadiusX="10" RadiusY="25"
               Width="100" Height="60" Margin="5"  HorizontalAlignment="Left"></Rectangle>
        <TextBlock Margin="5,5,0,0">Corner radius of 100 (X) and 60 (Y).</TextBlock>
        <Rectangle Fill="Yellow" Stroke="Blue" RadiusX="100" RadiusY="60"
               Width="100" Height="60" Margin="5"  HorizontalAlignment="Left"></Rectangle>
    </StackPanel>
</Window>
RoundedRectangles

 三、改变形状的尺寸和放置形状

  正如前面所知,赢编码尺寸通常不是创建用户界面的理想方法。它们会限制处理动态内容的能力,并会使应用程序本地化到其他语言变得更加困难。

  当绘制形状时,不再总是关心这些问题。通常,需要更严格地控制形状的位置。然而,在许多情况下仍需要灵活一点设计。Ellipse和Rectangle为了适应可用的空间,都能自动改变自身。

  如果为提供Height和Width属性,形状会根据它们的容器来设置自身的尺寸。在上一个示例中,如果删除Height和Width值(并且不设置MinHeight和MinWidth值),就会导致形状缩小到看不见,因为StackPanel面板为了适应其内容改变了尺寸。然而,如果强制StackPanel面板的宽度为整个窗口的宽度(通过将HorizontalAlignment属性设置为Stretch),并将椭圆的HorizontalAlignment属性设置为Stretch,删除椭圆的Width属性值,这时椭圆的宽度就是整个窗口的宽度。

  可使用Grid容器构造更好的示例。如果使用按比例改变行尺寸的行为(默认行为),就可使用下面更精简的标记创建填满窗口的椭圆:

<Grid>
    <Ellipse Fill="Yellow" Stroke="Blue"></Ellipse>
</Grid>

  在上面的标记中,Grid面板填满了整个窗口。Grid面板包含了一个按比例改变尺寸的行,该行填满了整个Grid面板。最后,椭圆填满了整行。

  改变形状尺寸的行为依赖于Stretch属性的值(该属性在Shape类中定义)。默认情况下,该属性被设置为Fill。如果改变指定明确的尺寸,这一设置会拉伸形状,使其填满容器。下表列出了Stretch属性的所有可能值。

表 Stretch枚举值

   下图显示了Fill、Uniform、UniformToFill枚举值之间的区别.

www.wityx.com www.wityx.com
<Window x:Class="Drawing.FillModes"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="FillModes" Height="270" Width="477"
    >
    <Grid ShowGridLines="True" Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="Auto"
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值