Зачем нужен Canvas в WPF и как позиционировать элементы вручную?
Во всех туториалах WPF используют StackPanel и Grid, а элементы сами выстраиваются. Но мне нужно расставить фигуры в произвольных координатах (рисую схему). Нашёл Canvas — как он работает и чем отличается от других панелей?
2 ответа
Canvas — это панель с абсолютным позиционированием. В отличие от Grid/StackPanel, она не раскладывает детей автоматически: вы сами задаёте координаты каждого элемента через присоединённые свойства Canvas.Left, Canvas.Top (а также Canvas.Right/Canvas.Bottom).
Пример со фигурами:
<Canvas Background="WhiteSmoke">
<Rectangle Canvas.Left="20" Canvas.Top="20"
Width="80" Height="50" Fill="SteelBlue"/>
<Ellipse Canvas.Left="150" Canvas.Top="40"
Width="60" Height="60" Fill="Tomato"/>
<Line X1="100" Y1="45" X2="150" Y2="70"
Stroke="Black" StrokeThickness="2"/>
<TextBlock Canvas.Left="20" Canvas.Top="90" Text="Схема"/>
</Canvas>
Ключевое:
Canvas.Left="20" Canvas.Top="20"— это присоединённое свойство (attached property): координаты живут «на ребёнке», но управляет ими Canvas;- начало координат — левый верхний угол, ось Y растёт вниз;
- элементы могут перекрываться (порядок по коду или через
Canvas.ZIndex).
Когда использовать Canvas:
- редакторы схем, диаграмм, графиков;
- игры, рисование, drag-and-drop фигур;
- любое место, где нужны точные пиксельные координаты.
Когда НЕ использовать: для обычных форм и адаптивных интерфейсов — там Canvas неудобен, потому что ничего не подстраивается под размер окна. Для таких задач берите Grid и StackPanel.
Задать координаты из C# можно так:
Canvas.SetLeft(myRect, 100);
Canvas.SetTop(myRect, 50);
Важное предупреждение: Canvas не умеет масштабироваться под размер окна — координаты фиксированы в пикселях. Если положить интерфейс на Canvas, при изменении размера окна всё останется на месте и появятся пустоты или обрезка.
Поэтому правило простое: Canvas — только для графики и схем, где абсолютные координаты осмысленны. Для форм всегда используйте Grid с колонками/строками и StackPanel — они адаптивные.