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

huangapple go评论72阅读模式
英文:

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.

&lt;Canvas&gt;
&lt;ItemsControl ItemsSource=&quot;{Binding ClickedPositions}&quot;&gt;
    &lt;ItemsControl.ItemTemplate&gt;
        &lt;DataTemplate&gt;
            &lt;Ellipse Width=&quot;5&quot; Height=&quot;5&quot; Fill=&quot;Red&quot;&gt;
                &lt;Ellipse.RenderTransform&gt;
                    &lt;TranslateTransform X=&quot;{Binding X}&quot; Y=&quot;{Binding Y}&quot; /&gt;
                &lt;/Ellipse.RenderTransform&gt;
            &lt;/Ellipse&gt;
        &lt;/DataTemplate&gt;
    &lt;/ItemsControl.ItemTemplate&gt;
&lt;/ItemsControl&gt;
&lt;/Canvas&gt;

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

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.

&lt;ItemsControl ItemsSource=&quot;{Binding ClickedPositions}&quot;&gt;
    &lt;ItemsControl.ItemsPanel&gt;
        &lt;ItemsPanelTemplate&gt;
            &lt;Canvas/&gt;
        &lt;/ItemsPanelTemplate&gt;
    &lt;/ItemsControl.ItemsPanel&gt;
    &lt;ItemsControl.ItemTemplate&gt;
        &lt;DataTemplate&gt;
            &lt;Ellipse Width=&quot;5&quot; Height=&quot;5&quot; Fill=&quot;Red&quot;&gt;
                &lt;Ellipse.RenderTransform&gt;
                    &lt;TranslateTransform X=&quot;{Binding X}&quot; Y=&quot;{Binding Y}&quot; /&gt;
                &lt;/Ellipse.RenderTransform&gt;
            &lt;/Ellipse&gt;
        &lt;/DataTemplate&gt;
    &lt;/ItemsControl.ItemTemplate&gt;
&lt;/ItemsControl&gt;

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

&lt;ItemsControl ItemsSource=&quot;{Binding ClickedPositions}&quot;&gt;
    &lt;ItemsControl.ItemsPanel&gt;
        &lt;ItemsPanelTemplate&gt;
            &lt;Canvas/&gt;
        &lt;/ItemsPanelTemplate&gt;
    &lt;/ItemsControl.ItemsPanel&gt;
    &lt;ItemsControl.ItemContainerStyle&gt;
        &lt;Style TargetType=&quot;ContentPresenter&quot;&gt;
            &lt;Setter Property=&quot;Canvas.Left&quot; Value=&quot;{Binding X}&quot;/&gt;
            &lt;Setter Property=&quot;Canvas.Top&quot; Value=&quot;{Binding Y}&quot;/&gt;
        &lt;/Style&gt;
    &lt;/ItemsControl.ItemContainerStyle&gt;
    &lt;ItemsControl.ItemTemplate&gt;
        &lt;DataTemplate&gt;
            &lt;Ellipse Width=&quot;5&quot; Height=&quot;5&quot; Fill=&quot;Red&quot;/&gt;
        &lt;/DataTemplate&gt;
    &lt;/ItemsControl.ItemTemplate&gt;
&lt;/ItemsControl&gt;

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:

&lt;ItemsControl ItemsSource=&quot;{Binding ClickedPositions}&quot;&gt;
    &lt;ItemsControl.ItemsPanel&gt;
        &lt;ItemsPanelTemplate&gt;
            &lt;Canvas/&gt;
        &lt;/ItemsPanelTemplate&gt;
    &lt;/ItemsControl.ItemsPanel&gt;
    &lt;ItemsControl.ItemContainerStyle&gt;
        &lt;Style TargetType=&quot;ContentPresenter&quot;&gt;
            &lt;Setter Property=&quot;Canvas.Left&quot; Value=&quot;{Binding X}&quot;/&gt;
            &lt;Setter Property=&quot;Canvas.Top&quot; Value=&quot;{Binding Y}&quot;/&gt;
        &lt;/Style&gt;
    &lt;/ItemsControl.ItemContainerStyle&gt;
    &lt;ItemsControl.ItemTemplate&gt;
        &lt;DataTemplate&gt;
            &lt;Path Fill=&quot;Red&quot;&gt;
                &lt;Path.Data&gt;
                    &lt;EllipseGeometry RadiusX=&quot;2.5&quot;, RadiusY=&quot;2.5&quot;/&gt;
                &lt;/Path.Data&gt;  
            &lt;/Path&gt;  
        &lt;/DataTemplate&gt;
    &lt;/ItemsControl.ItemTemplate&gt;
&lt;/ItemsControl&gt;

huangapple
  • 本文由 发表于 2023年7月6日 19:03:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76628153.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定