英文:
Drawing multiple items on wpf canvas results in each subsequent item being drawn below the previous even if using the same position values
问题
我试图在用户点击图像的位置绘制圆圈。我有一个与图像大小相同的画布来绘制它们。
我已经正确获取了点击的位置,并且我正在使用下面的代码来绘制椭圆,它几乎可以工作,只是每次连续点击下一个椭圆都会在前一个下方绘制,即使您沿着x轴移动,它仍然会在前一个下方绘制。
它下方绘制的量是椭圆的大小。
每次点击时,我都会将位置添加到名为ClickedPositions的observablecollection中。
<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>
在这里,您可以看到我在同一个位置点击了6次,第一个圆圈是正确的,然后每个连续的圆圈都在前一个下方绘制。然后我将鼠标移到右边并点击两次,您可以看到它仍然在前一个下方绘制。
我漏掉了什么?
谢谢。
英文:
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>
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.
What am I missing?
Thanks
答案1
得分: 0
以下是翻译好的内容:
需要将Canvas声明为ItemsControl的ItemsPanel。默认的ItemsPanel是垂直StackPanel。
<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>
您也可以设置项目容器的Ellipse的RenderTransform,也可以设置项目容器的Canvas.Left和Canvas.Top属性:
<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>
最后要注意,X和Y是Ellipse的边界框的左上角的坐标。为了绘制一个居中的形状,使用具有EllipseGeometry的Path:
<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>
英文:
The Canvas needs to be declared as the ItemsPanel
of the ItemsControl. The default ItemsPanel is a vertical StackPanel.
<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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论