Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Drawing multiple items on wpf canvas results in each subsequent item being drawn below the previous even if using the same position values

I’m trying to draw circles at places a user clicks on an image. I’ve got a canvas the same size as the image to draw them.
I’m getting the position of the clicks correctly, and I’m using the below code to draw the ellipses which almost works, just that each subsequent click the next ellipses is drawn below the previous, even if you move along the x axis, it still draws it below the previous.
The amount it’s drawn below is the size of the ellipse.
Each click I’m adding a position to the observablecollection called ClickedPositions.

<Canvas>
<ItemsControl ItemsSource="{Binding ClickedPositions}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Ellipse Width="5" Height="5" Fill="Red">
                <Ellipse.RenderTransform>
                    <TranslateTransform X="{Binding X}" Y="{Binding Y}" />
                </Ellipse.RenderTransform>
            </Ellipse>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>

enter image description here

Here you can see I clicked in the same place 6 times, the first circle is correct, then each subsequent circle is drawn ‘below’ the previous. Then I moved the mouse right and clicked twice, and you can see it’s still being drawn ‘below’ the previous.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

What am I missing?

Thanks

>Solution :

The Canvas needs to be declared as the ItemsPanel of the ItemsControl:

<ItemsControl ItemsSource="{Binding ClickedPositions}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Ellipse Width="5" Height="5" Fill="Red">
                <Ellipse.RenderTransform>
                    <TranslateTransform X="{Binding X}" Y="{Binding Y}" />
                </Ellipse.RenderTransform>
            </Ellipse>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Instead of setting the Ellipse’s RenderTransform, you may also set the Canvas.Left and Canvas.Top properties of the item container:

<ItemsControl ItemsSource="{Binding ClickedPositions}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding X}"/>
            <Setter Property="Canvas.Top" Value="{Binding Y}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Ellipse Width="5" Height="5" Fill="Red"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Finally be aware that X and Y are the coordinates of the upper left corner of the Ellipse’s bounding box. In order to draw a centered shape, use a Path with an EllipseGeometry:

<ItemsControl ItemsSource="{Binding ClickedPositions}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding X}"/>
            <Setter Property="Canvas.Top" Value="{Binding Y}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Path Fill="Red">
                <Path.Data>
                    <EllipseGeometry RadiusX="2.5", RadiusY="2.5"/>
                </Path.Data>  
            </Path>  
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading