Canvas(画布)可能是所有面板中最简单的。实际上,它不会默认做任何事,而是允许你把控件放在它的内部,然后显式地给这些控件定位。
如果您曾经使用过像WinForms这样的其他UI库,这可能会让您感觉很自在,但是尽管对所有的子控件都具有绝对的控制权是很诱人的,但这也意味着一旦用户开始调整窗口大小,Panel就不会为您做任何事情,比如绝对定位的文本或内容缩放。
更多的内容将在后面解释,我们现在看一个简单的示例。这个示例主要演示了,Canvas默认只会做很少的工作。
<Window x:Class="WpfTutorialSamples.Panels.Canvas"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Canvas" Height="200" Width="200">
<Canvas>
<Button>Button 1</Button>
<Button>Button 2</Button>
</Canvas>
</Window>
你可以看到,尽管我们有两个按钮,但它们都被放在完全相同的位置,因此只有后一个是可见的。Canvas完全不做任何事情,除非你给出了子控件的坐标。这可以使用Canvas控件中的Left,Right,Top和Bottom(左,右,顶和底)的关联属性完成。
这些属性允许你指定与Canvas的四条边相关的位置。默认情况下,它们被设置为NaN(Not a Number,非数字),这会让Canvas将它们放在左上角,但是如前所述,你可以简单地修改:
<Window x:Class="WpfTutorialSamples.Panels.Canvas"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Canvas" Height="200" Width="200">
<Canvas>
<Button Canvas.Left="10">Top left</Button>
<Button Canvas.Right="10">Top right</Button>
<Button Canvas.Left="10" Canvas.Bottom="10">Bottom left</Button>
<Button Canvas.Right="10" Canvas.Bottom="10">Bottom right</Button>
</Canvas>
</Window>
请注意,我只设置我需要的属性。对于前两个按钮,我只希望指定X轴的值,因此我指定左和右属性的值,将按钮从相应的方向推向中心。
对于底部的两个按钮,我使用左/右和底部两个属性将它们从对应的方向推向中心。 您通常要指定“上”或“下”值和/或“左”或“右”值。
如上所述,由于画布可以让您完全控制控件位置,因此不会真正关心是否有足够的空间容纳所有控件或者是否有一个位于另一个控件之上。这种行为使得画布对于几乎任何类型的对话框设计来说都是一个糟糕的选择。但正如其名称所暗示的那样,画布至少对于一件事情非常有用:绘画。WPF有一堆可以放在画布中的控件,使得画布可以做出漂亮的插图。
在下一个示例中,我们将使用WPF的几个形状相关控件来说明使用画布时另一个重要的概念:Z轴。通常,如果画布中的两个控件重迭,则标记中最后定义的控件将优先并覆盖其他控件。但是,通过在面板类上使用附加的Z坐标属性,可以轻松更改此行为。
首先,我们根本不使用z轴的示例:
<Window x:Class="WpfTutorialSamples.Panels.CanvasZIndex"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CanvasZIndex" Height="275" Width="260">
<Canvas>
<Ellipse Fill="Gainsboro" Canvas.Left="25" Canvas.Top="25" Width="200" Height="200" />
<Rectangle Fill="LightBlue" Canvas.Left="25" Canvas.Top="25" Width="50" Height="50" />
<Rectangle Fill="LightCoral" Canvas.Left="50" Canvas.Top="50" Width="50" Height="50" />
<Rectangle Fill="LightCyan" Canvas.Left="75" Canvas.Top="75" Width="50" Height="50" />
</Canvas>
</Window>
可以看到,因为每个矩形都是在圆之后定义的,所以它们都与圆重迭,并且每个矩形都覆盖在先前定义的圆上。 我们试着改变一下:
<Window x:Class="WpfTutorialSamples.Panels.CanvasZIndex"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CanvasZIndex" Height="275" Width="260">
<Canvas>
<Ellipse Panel.ZIndex="2" Fill="Gainsboro" Canvas.Left="25" Canvas.Top="25" Width="200" Height="200" />
<Rectangle Panel.ZIndex="3" Fill="LightBlue" Canvas.Left="25" Canvas.Top="25" Width="50" Height="50" />
<Rectangle Panel.ZIndex="2" Fill="LightCoral" Canvas.Left="50" Canvas.Top="50" Width="50" Height="50" />
<Rectangle Panel.ZIndex="4" Fill="LightCyan" Canvas.Left="75" Canvas.Top="75" Width="50" Height="50" />
</Canvas>
</Window>
默认的Z轴值为0,但我们为每个形状分配一个新值。规则是具有较高z坐标的元素会覆盖具有较低值的元素。 如果两个值相同,则最后定义的元素“胜”。从截图中可以看出,更改Z坐标属性改变了图形的外观。