WPF usercontrol结合了椭圆和箭头

时间:2022-11-21 17:42:44

I want to create a custom usercontrol to represent a player in a 2D map. I had an ellipse to represent the player but I want to have on the border of the ellipse an arrow to indicate where the player is looking.

我想创建一个自定义用户控件来表示2D地图中的玩家。我有一个椭圆来代表玩家,但我希望在椭圆的边框上有一个箭头来指示玩家在哪里看。

This is what I tried :

这是我试过的:

<Ellipse Width="17" Height="17" Stroke="Black" Fill="White" HorizontalAlignment="Center" />
    <Path Data="M5,0 0,5 5,10" Fill="White" Stroke="Black" VerticalAlignment="Center" >
        <Path.LayoutTransform>
            <RotateTransform Angle="10"/>
        </Path.LayoutTransform>
    </Path>

the result : WPF usercontrol结合了椭圆和箭头

结果 :

That looks like what I want (it's not properly aligned but that's not the point here).

这看起来像我想要的(它没有正确对齐,但这不是重点)。

The problems are :

问题是:

  • I know the position of the ellipse's center without the arrow

    我知道没有箭头的椭圆中心的位置

  • When the arrow will be on the right the relative position of the ellipse's center will be different --> I could solve this problem using a square control

    当箭头在右边时,椭圆中心的相对位置将不同 - >我可以使用方形控件来解决这个问题

  • My Circle has a textblock on top (Horitonzal + vertical center) to display its id
  • My Circle在顶部有一个文本块(Horitonzal +垂直中心)以显示其id

How to move the arrow depending on the position looked ? I thought the easier might be to calculate an angle and rotate the whole control.

如何根据位置移动箭头看?我认为更容易计算角度并旋转整个控件。

My first idea was to draw using any vector drawing software (illustrator for instance) the path, and get the coordinates of the path, and paste them in WPF.

我的第一个想法是使用任何矢量绘图软件(例如插图画家)绘制路径,并获取路径的坐标,并将它们粘贴到WPF中。

then just rotate the usercontrol. But doing this will also rotate the text and I don't want the text to rotate.

然后只需旋转用户控件。但这样做也会旋转文本,我不希望文本旋转。

I'm stuck on this one, I hope my problem is enough described to be understood.

我坚持这个,我希望我的问题足以被理解。

EDIT My first try :

编辑我的第一次尝试:

<ControlTemplate TargetType="ContentControl">
                        <Grid Width="34" Height="34">
                            <Path x:Name="contour_forme"
                              Stroke="{TemplateBinding BorderBrush}"
                              StrokeThickness="1"
                              Stretch="Uniform"
                              Width="28"
                              Height="22"
                              HorizontalAlignment="Left"
                              Fill="{TemplateBinding Background}"
                              Data="M28.857,53.500 C24.537,53.487 20.477,52.380 16.938,50.443 C16.938,50.443 16.938,50.500 16.938,50.500 C16.938,50.500 16.785,50.350 16.785,50.350 C12.845,48.157 9.579,44.924 7.317,41.032 C7.317,41.032 -6.176,27.755 -6.176,27.755 C-6.176,27.755 8.206,14.530 8.206,14.530 C10.380,11.316 13.289,8.649 16.681,6.736 C16.681,6.736 16.938,6.500 16.938,6.500 C16.938,6.500 16.938,6.581 16.938,6.581 C20.525,4.615 24.641,3.496 29.021,3.509 C42.835,3.551 53.996,14.775 53.951,28.580 C53.906,42.385 42.670,53.542 28.857,53.500 ZM29.004,8.507 C17.953,8.474 8.965,17.400 8.929,28.443 C8.893,39.487 17.822,48.467 28.873,48.500 C39.924,48.533 48.912,39.608 48.948,28.564 C48.985,17.520 40.056,8.540 29.004,8.507 Z"
                              >
                                <Path.LayoutTransform>
                                    <RotateTransform Angle="0" />
                                </Path.LayoutTransform>
                            </Path>
                            <TextBlock Style="{DynamicResource StyleTextes}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"
                                       Text="5"
                                       />
                        </Grid>
                    </ControlTemplate>

With the result :WPF usercontrol结合了椭圆和箭头 As you can see I didn't manage to center the text inside my 22px circle. My arrow is about 6 px height so I've created a control of 22 (circle's size expected) + 2 * 6px depending on the arrow position.

结果:正如您所看到的,我无法将文本置于22px圈内。我的箭头大约是6像素高,所以我创建了一个22的控件(预期的圆圈大小)+ 2 * 6px,具体取决于箭头位置。

But when I try to rotate my path doing :

但是,当我尝试旋转我的路径时:

<Path.LayoutTransform>         <RotateTransform Angle="90" />
                            </Path.LayoutTransform>

I have the following result : WPF usercontrol结合了椭圆和箭头

我有以下结果:

I'm not sure on how I can keep the circle of my path in the center of the control when I rotate the path.

当我旋转路径时,我不确定如何将路径的圆圈保持在控制中心。

1 个解决方案

#1


Just apply the RotateTransform to the "image" but not to the text.
Also I would use a render transform instead of a layout transform.

只需将RotateTransform应用于“图像”,但不应用于文本。我也会使用渲染变换而不是布局变换。

    <Canvas Canvas.Left="206.333" Canvas.Top="119" Height="80" Width="80">
    <Path Data="M244,99.333333 L210.16667,109.50034 244.83334,125.50034" Fill="#FFF4F4F5" Stretch="Fill" Stroke="Black"  RenderTransformOrigin="0.5,0.5" Height="60" Canvas.Left="3" Canvas.Top="5" Width="60">
        <Path.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform Angle="70"/>
                <TranslateTransform/>
            </TransformGroup>
        </Path.RenderTransform>
    </Path>
    <TextBlock TextWrapping="Wrap" Text="TextBlock" Height="20" Width="80" Canvas.Top="30" TextAlignment="Center"/>
    </Canvas>

#1


Just apply the RotateTransform to the "image" but not to the text.
Also I would use a render transform instead of a layout transform.

只需将RotateTransform应用于“图像”,但不应用于文本。我也会使用渲染变换而不是布局变换。

    <Canvas Canvas.Left="206.333" Canvas.Top="119" Height="80" Width="80">
    <Path Data="M244,99.333333 L210.16667,109.50034 244.83334,125.50034" Fill="#FFF4F4F5" Stretch="Fill" Stroke="Black"  RenderTransformOrigin="0.5,0.5" Height="60" Canvas.Left="3" Canvas.Top="5" Width="60">
        <Path.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform Angle="70"/>
                <TranslateTransform/>
            </TransformGroup>
        </Path.RenderTransform>
    </Path>
    <TextBlock TextWrapping="Wrap" Text="TextBlock" Height="20" Width="80" Canvas.Top="30" TextAlignment="Center"/>
    </Canvas>