【问题标题】:WPF Path sizing problemWPF路径大小问题
【发布时间】:2011-03-20 22:56:59
【问题描述】:

大家好,我一直在玩 WPF 的路径形状,但我对某些行为有点恼火。 具体来说,路径不会像我想要的那样自行调整大小。如果你看下面的图片,我想要的是整个路径都在白色方块内(代表路径控件的边界),但弧线有点悬空。我认为这是因为 Path 根据用于绘制形状的点来调整自身的大小,而不是根据实际绘制的形状。

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


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

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 " />

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

【问题讨论】:

    标签: wpf path size shape


    【解决方案1】:

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

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

    您所定义的正是正在生成的内容 - 您可以更改它的唯一方法是更改​​您的位置 - 但圆弧仍将超出 X 轴上的 Point0,因为这是您所定义的。

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

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

    【讨论】:

    • 这也是我对第一个样本的推断。但是当我使用迷你语言时,它的工作方式有所不同。在那种情况下,它确实是(几乎)完美的。
    • 第二个例子的路径数据来自哪里?
    • 第一个示例从数据绑定中获取数据,我只是手动检索该数据并将其插入到第二个示例中的数据字符串中。
    • 嗯...我只能猜测,由于形状的呈现方式不同,您的翻译有误。
    • 嗯,这总是有可能的。但它们确实产生了相同的形状——两条弧线和两条线,每条线的尺寸完全相同。我会继续插话,但我现在的猜测是,迷你语言对我们的作用比我们想象的要多。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      这是一个如何做到这一点的示例:

      首先(可选)在像Inkscape 或CorelDraw 这样的矢量程序中绘制你的形状!我使用 CorelDraw 创建了.svg File注意:当使用程序创建矢量时,将页面大小设置为 100 X 100 像素,这就是您要设置的画布大小。如果您手动编写路径,这也是一种非常方便的方法,只需选择 100 X 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>
      

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

      然后要使用它,只需在 ViewBox 中放置一个 ContentControl,该 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>
      

      您还可以做很多其他事情,您可以使用任何其他形状、效果、动画等做任何事情。

      【讨论】:

        猜你喜欢
        • 2011-01-15
        • 1970-01-01
        • 2015-12-16
        • 2012-05-28
        • 2011-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-03
        相关资源
        最近更新 更多