Подтвердить что ты не робот

Позиционирование элемента внутри холста по центру (вместо левого верхнего угла) с использованием только XAML в WPF

Общий вопрос о размещении элемента внутри Canvas: "Как позиционировать центр элемента (вместо верхнего левого угла)".

Представлены несколько решений, но все они имеют недостатки.

Самое простое решение - разместить размер элемента во время установки программных свойств Canvas.Left и Canvas.Top. Это работает, но только один раз. Это решение не поддерживает привязки, и оно будет ломаться при изменении размера элемента. Вы также не можете установить Canvas.Left или Canvas.Top, используя

Еще один набор решений включает преобразование переводов с использованием RenderTransform или Margin. Эти решения требуют привязки некоторого свойства к -0.5 * Width или -0.5 * Height. Такое связывание требует создания пользовательского ValueConverter и невозможно создать с использованием только XAML.

Итак, существует ли простой способ разместить элемент внутри холста так, чтобы его Canvas.Left и Canvas.Top соответствовали центру элемента, и оба свойства размера и положения могут быть связаны с некоторыми другими свойствами?

4b9b3361

Ответ 1

XAML и привязки кажутся очень мощными, но иногда есть простые проблемы, требующие очень сложных решений. В моей библиотеке привязок, создающей такую ​​привязку, было бы так же легко, как писать element.Center = position или element.TopLeft = position - element.Size / 2, но не позволяйте мне увлекаться.

Я нашел очень простое решение, которое использует только XAML и поддерживает привязку к размеру и положению свойств элемента. Похоже, что когда элемент управления WPF с установкой выравнивания слишком Stretch или Center помещается внутри холста, элемент "тяготеет" к центру в качестве точки (Canvas.Left, Canvas.Top) (состояние, которое мы желаем), но останавливается "угловая пластина", помещенная в ту же точку (Canvas.Left, Canvas.Top). Откуда я знаю об этом "гравитации"? Это видно, когда вы облегчите блок, установив Margin элемента в отрицательное значение. Установка отрицательного поля позволяет элементу двигаться к своей центральной цели. Элемент перемещается до тех пор, пока Margin не достигнет (-Height / 2, -Width / 2), чтобы элемент полностью центрировался в точке (Canvas.Left, Canvas.Top). Дальнейшие изменения не вызывают никакого движения, поскольку элемент уже идеально расположен.

Решение: установите Margin="-1000000".

Итак, в следующем коде эллипсы центрируются в точке (200, 200). Первый эллипс имеет свойства Left и Top, соответствующие центру эллипса, что позволяет легко связывать их с некоторыми свойствами других объектов.

<Canvas>
    <Ellipse Width="100" Height="100" Canvas.Left="200" Canvas.Top="200" Opacity="0.5" Fill="Red" Margin="-100000" />
    <Ellipse Width="100" Height="100" Canvas.Left="150" Canvas.Top="150" Opacity="0.5" Fill="Blue" />
</Canvas>

Плохо, что это решение работает только в WPF. Silverlight и WinRT не имеют описанного поведения.

Ответ 2

Еще проще, по крайней мере для Shapes, было бы использовать Path с соответствующей геометрией:

<Canvas>
    <Path Canvas.Left="200" Canvas.Top="200" Fill="Red" Opacity="0.5">
        <Path.Data>
            <EllipseGeometry RadiusX="50" RadiusY="50"/>
        </Path.Data>
    </Path>
</Canvas>

Ответ 4

Я решил это, поместив холст в нижнюю правую ячейку сетки 2x2. Это делает координату 0,0 центром сетки, а затем вы можете сделать весь рисунок относительно этого.