Convert a geometry to a path in wpf (with blend ?)

2019-02-11 00:10发布

问题:

my question is simple.

how can I convert this code:

<Path>
    <Path.Data>
        <EllipseGeometry Center="5,4" RadiusX="4" RadiusY="4"/>
    </Path.Data>
</Path>

into something like

<Path Data="M 0 5 L 3 10 10 0"/>

(please note that the second one produces a checkmark, not an ellipse. It was just for illustration purposes, and my goal is just that: find what sequence gives an ellipse)

edit: I also read the doc about Bezier curves in xaml and am fully aware that I could simply produce the right code by calculating the exact points of the Bezier curve to get an ellipse, but I do not wish to go to the hassle of doing this calculation myself, so I was wondering if there is an easy way to do this (in Blend maybe)

回答1:

This shows how to do it from code. I'm not sure if that'll solve your problem or not - you say "with blend?" in the title, and I'm not aware of a way to do this in Blend. But I hope this may help.

The first step would be to convert the EllipseGeometry into a PathGeometry:

var geom = new EllipseGeometry(new Point(5, 4), 4, 4);
var pathGeometry = PathGeometry.CreateFromGeometry(geom);

Once you've got a PathGeometry you can simply call ToString and it'll give you the string representation:

string pathText = pathGeometry.ToString();

On my system, this produces the following rather verbose text:

"M9,4C9,6.20913899932317 7.20913899932317,8 5,8 2.79086100067683,8 1,6.20913899932317 1,4 1,1.79086100067683 2.79086100067683,0 5,0 7.20913899932317,0 9,1.79086100067683 9,4z"

Now if you want to end up with exactly what you would have got if you'd fed that string into Xaml, you need one more step, because Xaml of the form you've supplied:

<Path Data="M 0 5 L 3 10 10 0"/>

doesn't produce a PathGeometry. It produces a StreamGeometry, which is a slightly more efficient, but fixed representation of the path. (The main difference being that you can't get hold of individual objects representing the various figures and segements in a StreamGeometry, whereas you can with a PathGeometry. StreamGeometry is cheaper, as a result.)

You can get a StreamGeometry from the path text:

var streamGeometry = StreamGeometry.Parse(pathText);

And then if you want that in a Path just build it:

var p = new Path { Data = streamGeometry };

Depending on what your exact goal is, there may be more efficient ways to do this. (StreamGeometry is a more efficient representation because it ends up creating far fewer objects. But the route by which my code gets to that representation is not very efficient, so you might be better off just stopping with the PathGeometry that the very first code snippet produces. Alternatively, if your goal is really just to get the path text, then the PathGeometry is also sufficient for your needs.)