is there any equivalent for System.Drawing.Drawing2D.GraphicsPath.AddArc, in Xaml UWP rendering ?
I have tried the below use case in XAML UWP up-to my knowledge.
Path path = new Path();
PathGeometry pathGeometry = new PathGeometry();
PathFigure pathFigure = new PathFigure();
ArcSegment arcSegment = new ArcSegment();
arcSegment.IsLargeArc = true;
arcSegment.Size = new Windows.Foundation.Size(100, 100);
arcSegment.Point = new Windows.Foundation.Point(100, 100);
arcSegment.RotationAngle = 180;
arcSegment.SweepDirection = SweepDirection.Clockwise;
pathFigure.StartPoint = new Windows.Foundation.Point(100, 100);
pathFigure.Segments.Add(arcSegment);
path.Data = pathGeometry;
path.Fill = new SolidColorBrush(Colors.Red);
path.StrokeThickness = 2;
pathGeometry.Figures.Add(pathFigure);
But the above is not 100% equivalent to System.Drawing.Drawing2D.GraphicsPath.AddArc(Rectangle, Single, Single)
is there any equivalent for System.Drawing.Drawing2D.GraphicsPath.AddArc, in Xaml UWP rendering ?
In classical windows form application, we have System.Drawing.Drawing2D namespace for drawing graphics. But this namespace is not supported in UWP app. UWP app has its own APIs for drawing graphics. You should be able to draw shapes by APIs under Windows.UI.Xaml.Shapes namespace. More details about how to draw shapes on uwp app please reference this article.
The method System.Drawing.Drawing2D.GraphicsPath.AddArc is actually for drawing a arc, which you already found in uwp app you could use adding ArcSegment instead.
But the above is not 100% equivalent to System.Drawing.Drawing2D.GraphicsPath.AddArc(Rectangle, Single, Single)
UWP app has its own APIs for drawing that it may not have a method that has same method name and same parameters as it in windows form. But you should be able to use other methods in uwp to implement the same effects. For example, the AddArc method has three parameters, Rectangle is for defined the x-diameter and y-diameter and the shape location, and startAngle and sweepAngle for defined the start and end angle. In uwp app, the ArcSegment can define the arc x-radius and y-radius by size property, and point for define start and end location.
For example, in a windows form, we may use the following code drawing a arc;
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// Create a GraphicsPath object.
GraphicsPath myPath = new GraphicsPath();
// Set up and call AddArc, and close the figure.
Rectangle rect = new Rectangle(20, 20, 50, 100);
myPath.StartFigure();
myPath.AddArc(rect, 0, 180);
myPath.CloseFigure();
// Draw the path to screen.
e.Graphics.DrawPath(new Pen(Color.Red, 3), myPath);
}
In uwp app you can do the same thing in xaml by the following code:
<Path StrokeThickness="2" Margin="40,40,0,0" Stroke="Red">
<Path.Data>
<PathGeometry>
<PathFigure IsClosed="True">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment Size="25,50" Point="50,0" IsLargeArc="True" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
Or code behind:
private void btnCreatepath_Click(object sender, RoutedEventArgs e)
{
Path path = new Path();
PathGeometry pathGeometry = new PathGeometry();
PathFigure pathFigure = new PathFigure();
ArcSegment arcSegment = new ArcSegment();
arcSegment.IsLargeArc = true;
arcSegment.Size = new Windows.Foundation.Size(25, 50);
arcSegment.Point = new Windows.Foundation.Point(50, 0);
arcSegment.RotationAngle = 180;
pathFigure.IsClosed = true;
pathFigure.Segments.Add(arcSegment);
path.Data = pathGeometry;
path.Stroke = new SolidColorBrush(Colors.Red);
path.StrokeThickness = 2;
path.Margin = new Thickness(40, 40, 0, 0);
pathGeometry.Figures.Add(pathFigure);
gridroot.Children.Add(path);
}
And the result:
In a word that you should be able find APIs to draw the same thing which you done in the form.
Related
I am trying to programmatically add bezier paths to a canvas in a WPF window. This works fine if I write them out in XAML, but adding one programmatically fails
XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="320" Width="480" ContentRendered="Window_ContentRendered">
<Canvas Margin="10" Name="canvas">
<Rectangle Width="50" Height="100" Fill="LightSalmon" Margin="0,50"></Rectangle>
</Canvas>
</Window>
Code behind
private void Window_ContentRendered(object sender, EventArgs e)
{
var r = new Rectangle();
r.Width = 50;
r.Height = 50;
r.StrokeThickness = 3;
r.Fill = new SolidColorBrush(Colors.Black);
canvas.Children.Add(r);
//bezier is a System.Windows.Shapes.Path
bezier.Stroke = new SolidColorBrush(Colors.Black);
bezier.StrokeThickness = 35;
PathFigure pf = new PathFigure { StartPoint = new Point(50, 67.5) };
PolyBezierSegment pbs = new PolyBezierSegment(new Point[] { new Point(100, 67.5), new Point(100, 50), new Point(150, 50) }, false);
pf.Segments.Add(pbs);
PathFigureCollection pfc = new PathFigureCollection { pf };
PathGeometry pg = new PathGeometry();
pg.Figures = pfc;
bezier.Data = pg;
canvas.Children.Add(bezier);
canvas.Dispatcher.Invoke(() => { }, DispatcherPriority.Render);
}
Since the black rectangle is added correctly it must be something with building up the bezier path, but I can't figure out where the problem is. There are no errors or exceptions. It just doesn't show up on re-rendering.
For completeness, here the (currently commented out) XAML of the bezier, that works
<Path Stroke="Black" StrokeThickness="30" Name="blackPath">
<Path.Data>
<PathGeometry>
<PathFigureCollection>
<PathFigure StartPoint="50,67.5">
<PolyBezierSegment Points="100,67.5 100,50 150,50" />
</PathFigure>
</PathFigureCollection>
</PathGeometry>
</Path.Data>
</Path>
Problem solved
PolyBezierSegment pbs = new PolyBezierSegment(
new Point[] { new Point(100, 67.5),
new Point(100, 50),
new Point(150, 50) },
false); // <== Wrong
should be
PolyBezierSegment pbs = new PolyBezierSegment(
new Point[] { new Point(100, 67.5),
new Point(100, 50),
new Point(150, 50) },
true); // <== Set to true if the Stroke is defined separately, which is the case for me
I have the scenario as follows, I am drawing an arc between two points in WPF, I need to fill the arc, but I want to fill the arc sector touching the center, but WPF fills up differently. How do I get the arc filled up the way I want?
PathGeometry pathGeometry = new PathGeometry();
PathFigure pathFigure = new PathFigure();
pathFigure.StartPoint = start;
ArcSegment arc = new ArcSegment(end, new Size(radiusX, radiusY), 0.0, large, d, true); //large & d corresponds to size & direction
pathFigure.Segments.Add(arc);
pathGeometry.Figures.Add(pathFigure);
SolidColorBrush fill = new SolidColorBrush(color);
drawingContext.DrawGeometry(fill, pen, pathGeometry);
My code produces the output as this :
whereas my requirement is this one:
Is there a way of getting this done? TIA.
Sure, you just need at add a line segment to go along with your arc segment.
PathGeometry pathGeometry = new PathGeometry();
PathFigure pathFigure = new PathFigure();
pathFigure.StartPoint = start;
ArcSegment arc = new ArcSegment(end, new Size(radiusX, radiusY), 0.0, large, d, true); //large & d corresponds to size & direction
pathFigure.Segments.Add(arc);
//line segment takes the path to the origin
LineSegment line = new LineSegment(new Point(originX, originY), true);
pathFigure.Segments.Add(line );
pathGeometry.Figures.Add(pathFigure);
SolidColorBrush fill = new SolidColorBrush(color);
drawingContext.DrawGeometry(fill, pen, pathGeometry);
I've stumbled upon converting Ellipse to PathGeometry.
I've tried to use ArcSegment to present Ellipse, but still don't know how to convert Ellipse size to ArcSegment size. I'm trying to segment Ellipse into two part, but there are other approaches, i.e. Bezier curves.
Need clues how to convert Ellipse to ArcSegment collection.
The whole process could be looking like that:
public static PathFigure ToFigures(this Ellipse ellipse)
{
var pathFigure = new PathFigure {IsClosed = true};
var arcSegment1 = new ArcSegment();
var arcSegment2 = new ArcSegment();
pathFigure.Segments.Add(arcSegment1);
pathFigure.Segments.Add(arcSegment2);
return pathFigure;
}
You could directly use an EllipseGeometry for the Path Data:
path = new Path
{
Data = new EllipseGeometry { RadiusX = 100, RadiusY = 50 }
};
Using the size of the Ellipse it would look like this:
path = new Path
{
Data = new EllipseGeometry
{
RadiusX = ellipse.ActualWidth / 2,
RadiusY = ellipse.ActualHeight / 2
}
};
I have a c# class library that supports Silverlight4 as well.
The problem is , I need to use System.Drawing.Drawing2d.GraphicsPath in my code. for drawing a shape. but it is not there in silverlight. Can anyone suggest me an alternative?
Thanks in advance.
Regards,
James
take a look at http://www.c-sharpcorner.com/UploadFile/mahesh/PathInSL03252009005946AM/PathInSL.aspx
Snippet XAML:
<Path Stroke="Black" StrokeThickness="4"
Data="M 80,200 A 100,50 45 1 0 100,50" />
Snippet Dynamic:
public void CreateAPath()
{
// Create a blue and a black Brush
SolidColorBrush blueBrush = new SolidColorBrush();
blueBrush.Color = Colors.Blue;
SolidColorBrush blackBrush = new SolidColorBrush();
blackBrush.Color = Colors.Black;
// Create a Path with black brush and blue fill
Path bluePath = new Path();
bluePath.Stroke = blackBrush;
bluePath.StrokeThickness = 3;
bluePath.Fill = blueBrush;
// Create a line geometry
LineGeometry blackLineGeometry = new LineGeometry();
blackLineGeometry.StartPoint = new Point(20, 200);
blackLineGeometry.EndPoint = new Point(300, 200);
// Create an ellipse geometry
EllipseGeometry blackEllipseGeometry = new EllipseGeometry();
blackEllipseGeometry.Center = new Point(80, 150);
blackEllipseGeometry.RadiusX = 50;
blackEllipseGeometry.RadiusY = 50;
// Create a rectangle geometry
RectangleGeometry blackRectGeometry = new RectangleGeometry();
Rect rct = new Rect();
rct.X = 80;
rct.Y = 167;
rct.Width = 150;
rct.Height = 30;
blackRectGeometry.Rect = rct;
// Add all the geometries to a GeometryGroup.
GeometryGroup blueGeometryGroup = new GeometryGroup();
blueGeometryGroup.Children.Add(blackLineGeometry);
blueGeometryGroup.Children.Add(blackEllipseGeometry);
blueGeometryGroup.Children.Add(blackRectGeometry);
// Set Path.Data
bluePath.Data = blueGeometryGroup;
LayoutRoot.Children.Add(bluePath);
}
I have created a c# windows application and written 75% of the code. The program allows the user to create a flow chart, and will shade the flow chart shapes according to their status. I wanted them to become 3d buttons such as from the website Webdesign.org
Rather than create a PNG for each button, I wanted to create them in C# using brushes or other technique, such as:
// Create solid brush.
SolidBrush blueBrush = new SolidBrush(Color.Blue);
// Create points that define polygon.
PointF point1 = new PointF(50.0F, 50.0F);
PointF point2 = new PointF(100.0F, 25.0F);
PointF point3 = new PointF(200.0F, 5.0F);
PointF point4 = new PointF(250.0F, 50.0F);
PointF point5 = new PointF(300.0F, 100.0F);
PointF point6 = new PointF(350.0F, 200.0F);
PointF point7 = new PointF(250.0F, 250.0F);
PointF[] curvePoints = {point1, point2, point3, point4, point5, point6, point7};
// Define fill mode.
FillMode newFillMode = FillMode.Winding;
// Fill polygon to screen.
e.Graphics.FillPolygon(blueBrush, curvePoints, newFillMode);
I know WPF has radial gradients, but can I do something simular in CGI?
Unlike WPF, GDI+/WinForms does not have a RadialGradientBrush. However you can achieve the same effect using a PathGradientBrush.
Here's an example:
Rectangle bounds = ...;
using (var ellipsePath = new GraphicsPath())
{
ellipsePath.AddEllipse(bounds);
using (var brush = new PathGradientBrush(ellipsePath))
{
brush.CenterPoint = new PointF(bounds.Width/2f, bounds.Height/2f);
brush.CenterColor = Color.White;
brush.SurroundColors = new[] { Color.Red };
brush.FocusScales = new PointF(0, 0);
e.Graphics.FillRectangle(brush, bounds);
}
}
The PathGradientBrush has lots of properties to experiment with to ensure you get the effect you're after.
Take a look at this Codeproject article, and then at the Path gradient.