Почему GeometryDrawing отображается на холсте с обрезанными координатами? - PullRequest
4 голосов
/ 11 января 2012

У меня есть следующий простой код, который рисует прямоугольник

    <Canvas Name="MainImageLayer" >
        <Image >
            <Image.Source >
                <DrawingImage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" >
                    <DrawingImage.Drawing >                            
                        <DrawingGroup>
                            <DrawingGroup.Children>
                                <GeometryDrawing>
                                    <GeometryDrawing.Pen>
                                        <Pen Brush="#FF1acc33" Thickness="1" />
                                    </GeometryDrawing.Pen>
                                    <GeometryDrawing.Brush>
                                        <SolidColorBrush>Red</SolidColorBrush>
                                    </GeometryDrawing.Brush>
                                    <GeometryDrawing.Geometry>
                                        <RectangleGeometry Rect="300,480,287,83" />
                                    </GeometryDrawing.Geometry>
                                </GeometryDrawing>

                            </DrawingGroup.Children>
                        </DrawingGroup>
                    </DrawingImage.Drawing>
                </DrawingImage>
            </Image.Source>                
        </Image>
    </Canvas>

Результат выглядит следующим образом - обратите внимание, что прямоугольник находится в (0,0) , даже если Rect определен как

<RectangleGeometry Rect="300,480,287,83" />

enter image description here

Я хочу, чтобы это началось с (300,480) , вот так:

enter image description here

Я могу добиться этого, проверив мой DrawingImage и выполнив:

            <Canvas.Top>300</Canvas.Top>
            <Canvas.Left>480</Canvas.Left>

Но нет ли лучшего способа, учитывая тот факт, что эти данные закодированы в Geometry ?

Ответы [ 2 ]

6 голосов
/ 11 января 2012

Ваша проблема связана с тем, что вся ваша геометрия обернута в объект «Изображение». По умолчанию свойства объекта .Height и .Width объекта Image установлены на «Авто», а свойство .Stretch установлено на «Унифицированный». Это гарантирует, что ваш прямоугольник всегда будет отображаться в верхнем левом углу холста.

Если вам действительно нужно инкапсулировать вашу геометрию в объекте «Изображение» (что я бы не рекомендовал вам делать), вам нужно будет установить «Поля вашего объекта изображения» на 300,480,0,0. чтобы ваш прямоугольник появился там, где вы хотите. Это необходимо из-за способа, которым объект Image обрабатывает свое содержимое.

Объект Image не ведет себя как объект Canvas, даже если он находится внутри него.

Если не существует какой-либо непреодолимой причины сохранить объект "Изображение", вы добьетесь гораздо большего успеха, если отбросите изображение и начнете рисовать непосредственно на холсте.

EDIT

Почему в этом случае не следует использовать объект Image?
Объект Image в основном используется для отображения ... ну, изображений, таких как растровые изображения и тому подобное. Он не подходит для рисования геометрии в определенном месте (и размере). Как и большинство элементов управления WPF, это то, что я бы назвал «относительным» элементом управления, что означает, что он хорошо подходит для автоматического изменения размера и позиционирования относительно его содержимого и его родителя. Canvas, с другой стороны, является примером «абсолютного» контроля. Вся причина его существования заключается в том, что он позволяет отображать контент в точном месте с точным размером. Добавление изображения внутри холста и последующее рисование геометрии внутри изображения просто добавляет ненужный слой сложности между холстом и геометрией, которую необходимо нарисовать.

Как можно добавить геометрию напрямую?
Один из самых простых способов - использовать объект Path, указанный в ответе Клеменса. Просто замените весь объект Image и все его содержимое на 5 строк этого пути, и ваш прямоугольник появится точно там, где и должен быть. Вы также можете сделать это с помощью одной строки и объекта Rectangle:

<Rectangle Height="83" Width="287" Margin="300,480,0,0" Stroke="#FF1acc33" StrokeThickness="1" Fill="Red" />

но я бы порекомендовал Path, так как он содержит размеры прямоугольника и в одном наборе чисел. Путь также дает вам гораздо большую гибкость, если вы работаете с фигурами, отличными от прямоугольников.

2 голосов
/ 11 января 2012

Похоже, DrawingImage (или GeometryDrawing?) Каким-то образом настроен на его видимый прямоугольник.В любом случае, не будет ли это намного более простым решением, вместо Image?

<Path Stroke="#FF1acc33" StrokeThickness="1" Fill="Red">
    <Path.Data>
        <RectangleGeometry Rect="300,480,287,83" />
    </Path.Data>
</Path>

Вы также можете добавить еще один непустой GeometryDrawing, который охватывает (0,0) (например, RectangeGeometry с Rect = "0, 0,1,1 ") с прозрачной кистью для DrawingGroup.

РЕДАКТИРОВАТЬ: Как я понял, DrawingImage настроен на Drawing.Bounds

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...