将路径转换为几何形状

8

大家好,我试图总结并提出一个基本问题和我的想法,但目前还没有成功:S

基本上我的问题是: 用户将元素添加在一起,我想基于这些数字创建一个新元素,以便为用户定义的元素创建新路径。比如说,我有一个正方形和一个三角形。用户将它们组合成一座房子。现在我想让这个房子成为用户的一个元素。为此,我需要该元素的路径,我该如何创建它?

我的想法 所使用的图形元素基于路径字符串。因此,我希望将它们转换为几何元素,以便稍后使用。我使用André Meneses在下面的答案中提供的代码,代码如下:

public static Geometry PathMarkupToGeometry(ShieldGearViewModel shieldGearModelRec)
    {
        string pathMarkup = shieldGearModelRec.Gear.Path;
        try
        {
            string xaml =
            "<Path " +
            "xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>" +
            "<Path.Data>" + pathMarkup + "</Path.Data></Path>";
            var path = System.Windows.Markup.XamlReader.Load(xaml) as System.Windows.Shapes.Path;
            // Detach the PathGeometry from the Path
            if (path != null)
            {
                path.Height = shieldGearModelRec.Gear.Height;
                path.Width = shieldGearModelRec.Gear.Width;
                path.Fill = new SolidColorBrush(Colors.Green);
                path.Stretch = Stretch.Fill;
                Geometry geometry = path.Data;
                //Test not working, exception is thrown
                //Rect transRect = new Rect(shieldGearModelRec.Gear.x, shieldGearModelRec.Gear.y, shieldGearModelRec.Gear.Width, shieldGearModelRec.Gear.Height);
                //geometry.Transform.TransformBounds(transRect);
                path.Data = null;
                return geometry;
            }
            return null;
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
        return null;
    }

我这样做是为了使几何图形可以按照此链接描述的示例进行操作。以上方法的问题在于,我无法访问新几何元素的x或y位置,那么如何指定此位置呢?
对于位置,我认为此链接可能是一个解决方案,只是还没有让它起作用?:)
完成后,我将其添加到基于前面的链接的geometrygroup中,以便我可以获得新元素的路径。但是geometrygroup的边界为0。
因此,为了使其工作,我需要为各个几何元素定义x和y,然后这可能会解决geomtrygroup问题,否则我必须在此之后查看:) 问题已经存在太长时间了:|
我有一个字符串,想要在代码背后将其转换为几何形状。因此,在Stackoverflow上找到了这个WPF C# Path: How to get from a string with Path Data to Geometry in Code (not in XAML)
该链接建议可以使用以下代码通过解析将字符串转换为路径:
var path = new Path();
path.Data = Geometry.Parse("M 100,200 C 100,25 400,350 400,175 H 280");

然而,在Windows Phone上parse不可用。我的其他尝试都没有解决这个问题。我尝试使用pathGeometry,但好像无法将字符串设置为路径?所以我的问题是如何在代码后台将字符串转换为几何形状,而不是绑定到视图元素。
第一步,我成功地创建了以下路径。
var pathTesting = new System.Windows.Shapes.Path();
var b = new System.Windows.Data.Binding
{
    Source = DecorationOnShield[i].Gear.Path
};
System.Windows.Data.BindingOperations.SetBinding(pathTesting, System.Windows.Shapes.Path.DataProperty, b);

现在我正在尝试将路径转换为几何形状。 附加信息 我的想法是和this link describes一样。示例中显示的内容如下:
var blackRectGeometry = new RectangleGeometry();
Rect rct = new Rect();
rct.X = 80;
rct.Y = 167;
rct.Width = 150;
rct.Height = 30;
blackRectGeometry.Rect = rct;

但我希望使用任意形状的路径,而不是矩形,但仍然能够设置诸如坐标和大小之类的信息。 额外 我想定义一个用户控件,只包含一个看起来像这样的路径:
<UserControl x:Class="UndoRedoShield.View.Geometry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP8"
mc:Ignorable="d"
Canvas.Left="{Binding Gear.x}" Canvas.Top="{Binding Gear.y}">


<Path Data="{Binding Gear.Path}" Fill="{Binding Gear.Color}" Stretch="Fill" UseLayoutRounding="False" Height="{Binding Gear.Height}" Width="{Binding Gear.Width}" Opacity="{Binding Gear.Opacity}">
    <Path.RenderTransform>
        <ScaleTransform ScaleX="{Binding Gear.Scale}" ScaleY="{Binding Gear.Scale}"/>
    </Path.RenderTransform>

</Path>

</UserControl>

但是无法在几何方面以任何方式使用它。有人有使用这种方法的想法吗?欢迎任何方法! :)
额外的问题:)
是否可以使用uielements创建几何形状,以便呈现的用户控件可以转换为几何路径?
进展
我发现this link,可以从路径创建几何图形。路径具有宽度和高度属性。
但是我在几何或路径中没有以下属性:
1. Canvas.Left 2. Canvas.Top 3. Canvas.ZIndex(我认为将其添加到GeometryGroup时可能会出现)
似乎可以通过Path.Data的边界属性完成此操作。但没有ZIndex。因此,仍需要使用GeometryGroup进行测试,并将Geometry添加到GeometryGroup中。

1
根据MSDN,“Geometry.Parse”可用于以下平台:Windows Phone 8.1,Windows Phone 8。您正在开发哪个版本的Windows Phone? - Abolfazl Hosnoddin
Windows Phone 8,可能会在将来升级到Windows Phone 8.1。所以Geometry.Parse不起作用? - JTIM
1
你所说的“不起作用”是指什么?是因为你的项目类型和版本不支持它,还是调用Parse方法时没有得到正确的结果? - Abolfazl Hosnoddin
它不可用。我已经更新了所有内容,可以访问所有几何对象,但Geometry.Parse不可用。我找到了一个解决方法。所以这并不是真正的问题。 - JTIM
2个回答

7

前一段时间,我在寻找解决方案时,创建了这个函数。也许它能帮到你。

    public static Geometry PathMarkupToGeometry(string pathMarkup)
    {
        try
        {
            string xaml =
            "<Path " +
            "xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>" +
            "<Path.Data>" + pathMarkup + "</Path.Data></Path>";
            var path = XamlReader.Load(xaml) as Path;
            // Detach the PathGeometry from the Path
            if (path != null)
            {
                Geometry geometry = path.Data;
                path.Data = null;
                return geometry;
            }
            return null;
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
        return null;
    }

然后我这样调用这个函数:

     var arrow = new Path
     {
        Data = DesignHelpers.PathMarkupToGeometry("M-1,0 L0,1 L1,0"),
        Fill = new SolidColorBrush(Colors.Black),
        Stretch = Stretch.Fill,
        Height = 12,
        Width = 18,
        HorizontalAlignment = HorizontalAlignment.Center
    };

我不知道这是否完全符合您的需求,但或许可以提供帮助。

谢谢,我今晚会测试它。 - JTIM
声明箭头元素后,您可以执行以下操作:Canvas.SetTop(arrow, 10); Canvas.SetLeft(arrow, 20); Canvas.SetZIndex(arrow, 30);然后,您必须将箭头元素放入画布中才能使其正常工作... - meneses.pt
好的,我觉得我做错了。因为我想把它们插入到GeometryGroup中,以创建一个像WPF中这个链接(http://www.c-sharpcorner.com/uploadfile/mahesh/path-in-wpf/)中的元素。看起来我还没有找到正确解决我的问题的方法,该死 :) - JTIM
但是路径由GeometryGroup组成,这里已经有了路径。如果不是为了创建路径,为什么要创建GeometryGroup呢? - meneses.pt
根据您的示例,您有一个三角形作为Path对象和一个正方形作为Path对象,您将它们添加到一个新的Canvas对象中,定义这些属性(Top、Left、ZIndex),然后您可以将您的canvas对象添加到ViewBox对象中并将其用作新控件,或将其放入用户控件中。这对您有帮助吗? - meneses.pt
显示剩余8条评论

3

Geometry.Parse(据我所知,它的后端StreamGeometry也是如此)确实在Windows Phone平台上缺失,但根据这个页面:http://msdn.microsoft.com/en-us/library/ms752293(v=vs.110).aspx

WPF提供了两个类来提供用于描述几何路径的小语言:StreamGeometry和PathFigureCollection。

PathFigureCollection 可用于 Windows Phone,因此这看起来是需要检查的地方:

http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.media.pathfigure(v=vs.105).aspx

现在你只需要能够从XAML样式标记中创建PathGeometry即可。看起来这里有一些生成路径的示例,使用XAML语法:

将XAML PathGeometry转换为WPF PathGeometry

Windows Phone 7:如何解析Bezier路径字符串,就像在XAML中一样?

基本上就是这样

string data = "M 100,200 C 100,25 400,350 400,175 H 280";
Path path = XamlReader.Load("<Path Data='" + data + "'/>") as Path;

谢谢。也许这是更好的制作路径的方法。但是关于创建几何图形,它使我能够设置各种变量作为位置。由于我现在无法测试它,你说这可以通过PathFigureCollection或PathGeometry实现吗? - JTIM
1
您应该能够设置任何可以通过XAML设置的内容。这种技术的主要限制似乎是在创建路径后无法编辑/更改路径。 - steve cook
终于有时间测试了一下,但好像不起作用。你提到的链接似乎是指你可以访问xaml代码和引用方式,但我不想指定xaml代码。我在问题中展示的第一步获取了一个路径,将其绑定到类型为System.Windows.Shapes.Path的变量上。我想用它来创建一个图形或几何体,但是你提出的链接和解决方案似乎行不通。 - JTIM
XAML 代码只是您路径描述的包装器。我已经更新了示例。 - steve cook

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接