This article has been localized into Russian by the community.
Панель типа Canvas
Canvas, вероятно, самая простая панель из доступных. По умолчанию она действительно ничего не делает, она просто позволяет вам вводить в него элементы управления, а затем располагать их вручную, используя явное задание координаты.
Если Вы когда-либо использовали другую библиотеку пользовательского интерфейса, такую как WinForms, это, вероятно, заставит Вас чувствовать себя как дома. Но, хотя это может быть заманчиво - иметь абсолютный контроль над всеми дочерними элементами управления, это также означает, что 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, поэтому я использую свойства Left и Right, чтобы сместить кнопки по направлению к центру, с каждой стороны.
Для нижних кнопок я использую как Left/Right, так и Bottom, чтобы направить их в центр в обоих направлениях. Обычно вы указываете либо верхнюю, либо нижнее значение и/или левое или правое значение.
Как уже упоминалось, поскольку Canvas дает Вам полный контроль над позициями, ему все равно, хватит ли места для всех ваших элементов управления или они перекрываются. Это делает его плохим выбором для практически любого типа диалогового дизайна, но Canvas, как следует из названия, отлично подходит как минимум одного: рисования. WPF имеет множество элементов управления, которые вы можете разместить внутри Canvas, чтобы сделать красивые иллюстрации.
Z-Index
В следующем примере мы будем использовать пару связанных с формой элементов управления WPF, чтобы проиллюстрировать еще одну очень важную концепцию при использовании Canvas: Z-Index. Обычно, если два элемента управления внутри Canvas перекрываются, один из них, определенный последним в разметке, будет иметь приоритет и перекрывать другие. Однако, используя свойство ZIndex в классе Panel, это можно легко изменить.
Для начала, пример, когда мы вообще не используем z-index:
<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>
Значение ZIndex по умолчанию равно 0, но мы назначаем новое для каждой из фигур. Правило состоит в том, что элемент с более высоким z-индексом перекрывает те, что имеют более низкие значения. Если два значения идентичны, последний определенный элемент «выигрывает». Как видно из скриншота, изменение свойства ZIndex дает совсем другой вид.