WPF路径大小问题

发布于 2024-10-24 07:55:04 字数 4091 浏览 2 评论 0原文

嘿伙计们,我一直在研究 WPF 的路径形状,但我对某些行为有点恼火。 具体来说,路径的大小并不像我想要的那样。如果您看下图,我想要的是整个路径位于白色方块内(代表路径控件的边界),但弧线有点悬垂。我认为这是因为路径根据用于绘制形状的点调整自身大小,而不是根据实际绘制的形状。

我的问题是:有谁知道如何克服这个问题?我的意思是,除了明确设置路径的尺寸之外。是否有一些我忽略的选项,以便根据形状而不是根据用于制作形状的点来调整路径本身的大小?感谢您的任何答复。

我的数据绑定路径问题 我的迷你语言路径问题


这是(应该是)等效代码的两个版本:

1)第一个,使用数据绑定(以非常详细的方式编写):

<UserControl x:Class="OrbitTrapWpf.LineSegmentTool"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:local="clr-namespace:OrbitTrapWpf"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300"
         x:Name="Root" Background="White">
<UserControl.Resources>
    <local:ArcSizeConverter x:Key="ArcSizeConverter"/>
    <local:ArcPointConverter x:Key="ArcPointConverter"/>
</UserControl.Resources>
<Path Name="path" Stroke="Black">
  <Path.Data>
    <PathGeometry>
      <PathGeometry.Figures>
        <PathFigureCollection>
          <PathFigure IsClosed="True">
            <PathFigure.StartPoint>
              <Binding ElementName="Root" Path="point0"></Binding>
            </PathFigure.StartPoint>
            <PathFigure.Segments>
              <PathSegmentCollection>
                <ArcSegment SweepDirection="Counterclockwise" >
                  <ArcSegment.Size>
                    <Binding ElementName="Root" Path="Radius" Converter="{StaticResource ArcSizeConverter}"/>
                  </ArcSegment.Size>
                  <ArcSegment.Point>
                    <Binding ElementName="Root" Path="point1" />
                  </ArcSegment.Point>
                </ArcSegment>
                <LineSegment>
                  <LineSegment.Point>
                    <Binding ElementName="Root" Path="point2" />
                  </LineSegment.Point>
                </LineSegment>
                <ArcSegment SweepDirection="Counterclockwise">
                  <ArcSegment.Size>
                    <Binding ElementName="Root" Path="Radius" Converter="{StaticResource ArcSizeConverter}"/>
                  </ArcSegment.Size>
                  <ArcSegment.Point>
                    <Binding ElementName="Root" Path="point3" />
                  </ArcSegment.Point>
                </ArcSegment>
              </PathSegmentCollection>
            </PathFigure.Segments>
          </PathFigure>
        </PathFigureCollection>
      </PathGeometry.Figures>
    </PathGeometry>
  </Path.Data>
</Path>

2)这个,使用迷你语言:

<UserControl x:Class="OrbitTrapWpf.LineSegmentTool"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:local="clr-namespace:OrbitTrapWpf"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300"
         x:Name="Root" Background="White">
<UserControl.Resources>
    <local:ArcSizeConverter x:Key="ArcSizeConverter"/>
    <local:ArcPointConverter x:Key="ArcPointConverter"/>
</UserControl.Resources>
  <Grid Name="grid">
  <Path Name="path" Stroke="Black" Data="M 0.146446609406726,1.14644660940673 A 0.5,0.5 0 1 0 0.853553390593274,1.85355339059327 L 1.85355339059327,0.853553390593274 A 0.5,0.5 0 1 0 1.14644660940673,0.146446609406726 Z " />

我认为两者应该大致相同,但显然迷你语言版本的大小几乎正确,而原始版本却有很大不同。

Hey guys, I've been playing around with WPF's Path shape, but I'm a bit annoyed with some behaviour.
Specifically, the path does not size itself as I would like. If you look at the image below, what I want is for the entire path to be within the white square (which represents the bounds of the Path control), but the arcs hang out a bit. I think this is because Path sizes itself according to the points used to draw the shape, and not according to the shape that is actually drawn.

My question is: does anyone know how to overcome this? I mean, aside from explicitly setting the dimensions of the path. Is there some option that I have overlooked in order to get the path to size itself according to the shape, and not according to the points used to make the shape? Thanks for any answers.

My path problem with data bindings My path problem with mini-language


Here's two versions of (what should be) equivalent code:

1) First, using databindings (written out in a very verbose manner):

<UserControl x:Class="OrbitTrapWpf.LineSegmentTool"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:local="clr-namespace:OrbitTrapWpf"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300"
         x:Name="Root" Background="White">
<UserControl.Resources>
    <local:ArcSizeConverter x:Key="ArcSizeConverter"/>
    <local:ArcPointConverter x:Key="ArcPointConverter"/>
</UserControl.Resources>
<Path Name="path" Stroke="Black">
  <Path.Data>
    <PathGeometry>
      <PathGeometry.Figures>
        <PathFigureCollection>
          <PathFigure IsClosed="True">
            <PathFigure.StartPoint>
              <Binding ElementName="Root" Path="point0"></Binding>
            </PathFigure.StartPoint>
            <PathFigure.Segments>
              <PathSegmentCollection>
                <ArcSegment SweepDirection="Counterclockwise" >
                  <ArcSegment.Size>
                    <Binding ElementName="Root" Path="Radius" Converter="{StaticResource ArcSizeConverter}"/>
                  </ArcSegment.Size>
                  <ArcSegment.Point>
                    <Binding ElementName="Root" Path="point1" />
                  </ArcSegment.Point>
                </ArcSegment>
                <LineSegment>
                  <LineSegment.Point>
                    <Binding ElementName="Root" Path="point2" />
                  </LineSegment.Point>
                </LineSegment>
                <ArcSegment SweepDirection="Counterclockwise">
                  <ArcSegment.Size>
                    <Binding ElementName="Root" Path="Radius" Converter="{StaticResource ArcSizeConverter}"/>
                  </ArcSegment.Size>
                  <ArcSegment.Point>
                    <Binding ElementName="Root" Path="point3" />
                  </ArcSegment.Point>
                </ArcSegment>
              </PathSegmentCollection>
            </PathFigure.Segments>
          </PathFigure>
        </PathFigureCollection>
      </PathGeometry.Figures>
    </PathGeometry>
  </Path.Data>
</Path>

2) And this one, using the mini-language:

<UserControl x:Class="OrbitTrapWpf.LineSegmentTool"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:local="clr-namespace:OrbitTrapWpf"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300"
         x:Name="Root" Background="White">
<UserControl.Resources>
    <local:ArcSizeConverter x:Key="ArcSizeConverter"/>
    <local:ArcPointConverter x:Key="ArcPointConverter"/>
</UserControl.Resources>
  <Grid Name="grid">
  <Path Name="path" Stroke="Black" Data="M 0.146446609406726,1.14644660940673 A 0.5,0.5 0 1 0 0.853553390593274,1.85355339059327 L 1.85355339059327,0.853553390593274 A 0.5,0.5 0 1 0 1.14644660940673,0.146446609406726 Z " />

I thought that the two should be roughly the same, but apparently the mini-language version sizes nearly correctly, while the original is much different.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

叹沉浮 2024-10-31 07:55:04

基本上,您的路径 xaml 所说的是:

  1. 从 Point0 开始,绘制一条到 Point1 的圆弧。
  2. 从 Point1 画一条线到 Point2。
  3. 从 Point2 绘制一条弧到 Point 3。
  4. “IsClosed”绘制另一条从 Point3 到 Point0 的线。

在此处输入图像描述

您定义的内容正是正在生成的内容 - 您可以更改它的唯一方法就是更改您的位置 - 但弧线仍将延伸到 X 轴上的 Point0 之外,因为这是您所定义的。

如果你需要你的形状完全适合某个边界,你可以在你的形状周围放置一个边框,在底部和右侧留出例如 1/2 半径的边距(我确信有一个精确突出的公式) 。

由于第二个屏幕截图看起来与第一个屏幕截图不同,因此我得出结论,它们是不同的形状 - 这只能意味着路径数据转换不正确。

Basically, what your path xaml says, is:

  1. Start at Point0, draw an arc to Point1.
  2. From Point1, draw a line to Point2.
  3. From Point2, draw an arc to Point 3.
  4. 'IsClosed' draws another line from Point3 to Point0.

enter image description here

What you've defined is exactly what is being produced - the only way you can change it is to change your positions - but the arc will still extend beyond Point0 on the X axis because that's what you have defined.

If you need your shape to fit entirely within some boundary, you can put a border around your shape, with margin of, say, 1/2 radius (I'm sure there is a formula for the exact protrusion) at the bottom and right.

Since the second screenshot looks different to the first, I would conclude that they are different shapes - which can only mean that the path data was translated incorrectly.

兔姬 2024-10-31 07:55:04

好的,所以我找到了问题并解决了。我在迷你语言版本中设置了 IsLargeArc 标志,而在纯 XAML 版本中,我将其保留为 False。于是我把它改为True,然后我神奇地得到了我期望的结果。

这对我来说似乎是一个错误,因为在这种情况下,大弧和小弧是一样的,因为我正在绘制半弧。如果有人知道这种行为的原因,那就太棒了!

Okay, so I found the problem and solved it. I had set the IsLargeArc flag in the mini-language version, while in the purely XAML version I had left this as False. So I changed it to True, and I magically got the results I expected.

This seems to be a bug to me, because in this case the large and small arcs are one and the same, since I am drawing a half-arc. If anyone knows a reason for this behaviour, it would be awesome to hear about it!

野生奥特曼 2024-10-31 07:55:04

我偶然发现了这篇文章,并认为我会发布一个答案,以防有人正在寻找一种调整路径或图标大小的简单方法。我发现的最简单的方法是对所有路径显示使用视图框。这是因为路径会在 Viewbox 内很好地自行缩放。我使用画布来保存每条路径,如果您希望能够使用“好”数字,则该画布的大小非常重要。

以下是如何执行此操作的示例:

首先(可选)在矢量程序中绘制形状,例如 Inkscape或 CorelDraw!我使用 CorelDraw 创建了 .svg 文件注意:当使用程序创建矢量时,将页面大小设置为 100 X 100 像素,这就是您要设置的画布大小。如果您用手写路径,这也是一种非常方便的方法,只需选择 100 X 100 之类的尺寸,所有路径测量值都小于 100。换句话说,100 使用它作为你的尺度。

接下来使用 Vector to Xaml Converter 等翻译程序并生成路径。将其保存到资源字典中或将其放入您需要的文件中。将路径放入画布中,如下所示:

<Canvas x:Key="someName" Width="100" Height="100">
    <Path Fill="#FF000000" Stroke="#FF373435" StrokeThickness="1" Data="M92,8L92,8C103,18,103,35,92,45L45,92C35,103,18,103,8,92L8,92C-3,82,-3,65,8,55L55,8C65,-3,82,-3,92,8z"/>
</Canvas>

再次注意画布的大小,这应该与“绘图板”的尺寸相匹配。

然后,要使用它,只需将 ContentControl 放入 ViewBox 中,该 ViewBox 具有您希望路径显示的宽度和高度,如下所示:

<Viewbox x:Name="btnClose" Width="30" Height="30">
    <ContentControl Content="{StaticResource someName}" />
</Viewbox>

就是这样!使用路径的另一个好处是您可以绑定背景(填充)或前景(描边)的颜色。以我们这里的示例为例,说明如何控制颜色:

<SolidColorBrush x:Key="stForeColor" Color="#FFD4D7EA" />

<Canvas x:Key="someName" Width="100" Height="100">
    <Path Fill="{StaticResource stForeColor}" Stroke="Transparent" StrokeThickness="1" Data="M92,8L92,8C103,18,103,35,92,45L45,92C35,103,18,103,8,92L8,92C-3,82,-3,65,8,55L55,8C65,-3,82,-3,92,8z"/>
</Canvas>

您还可以执行大量其他操作,可以对任何其他形状、效果、动画等执行任何操作。

I ran across this post and thought I would post an answer in case anyone is looking for a easy way to resize paths or Icons. The easiest way I have found is by using a Viewbox for all of my Path displays. This is because a path will scale itself nicely inside of a Viewbox. I use a Canvas to hold each path, the size of this Canvas is very important if you want to be able to use "Nice" numbers.

Here is a example of how to do this:

First (Optional) Draw your shape in a Vector Program like Inkscape or CorelDraw! I used CorelDraw to create the .svg File. Note: When using a program to create a vector make your page size something like 100 X 100 Pixels this is what you are going to set your Canvas Size to. If you are writing the path by hand this is also a very handy approach just pick a size like 100 X 100 and all of your path measurements are < 100 use that as your scale in other words.

Next use a translator program like Vector to Xaml Converter and generate a path. Save this into a Resource Dictionary or put it in the file where you need it. Put the Path inside a Canvas like so:

<Canvas x:Key="someName" Width="100" Height="100">
    <Path Fill="#FF000000" Stroke="#FF373435" StrokeThickness="1" Data="M92,8L92,8C103,18,103,35,92,45L45,92C35,103,18,103,8,92L8,92C-3,82,-3,65,8,55L55,8C65,-3,82,-3,92,8z"/>
</Canvas>

Again note the size of the Canvas, this should match the dimensions of your "Drawing Board".

Then to use this just put a ContentControl inside of a ViewBox that has the Width and Height that you want the Path to display at like so:

<Viewbox x:Name="btnClose" Width="30" Height="30">
    <ContentControl Content="{StaticResource someName}" />
</Viewbox>

Thats it! Another nice thing about using Paths is you can bind the Color of hte Background (Fill) or Foreground (Stroke). Taking our example here is how to control the Colors:

<SolidColorBrush x:Key="stForeColor" Color="#FFD4D7EA" />

<Canvas x:Key="someName" Width="100" Height="100">
    <Path Fill="{StaticResource stForeColor}" Stroke="Transparent" StrokeThickness="1" Data="M92,8L92,8C103,18,103,35,92,45L45,92C35,103,18,103,8,92L8,92C-3,82,-3,65,8,55L55,8C65,-3,82,-3,92,8z"/>
</Canvas>

There are also tons of other things that you can do, anything that you can do with any other Shape, Effects, Animations etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文