I have a uniform grid that has rectangles dynamically added to it. I want to remove a particular rectangle, but I am getting the following error when trying to pass it to the Remove method:
Cannot convert from 'System.Drawing.Rectangle' to 'System.Windows.UIElement'
My code is:
Rectangle swatch = (Rectangle)ug_Thumbnails.FindName("s_" + _instance);
ug_Thumbnails.Children.Remove(swatch);
I tried casting, and got an error saying that you couldn't do it.
EDIT: Per request, here's the code to create the rectangle:
System.Windows.Shapes.Rectangle swatch = new System.Windows.Shapes.Rectangle();
swatch.Width = 50;
swatch.Height = 50;
swatch.Margin = new Thickness(0, 5, 5, 0);
swatch.StrokeThickness = 1;
swatch.Stroke = System.Windows.Media.Brushes.Gray;
swatch.Name = "s_" + name.ToString();
double groupsize = 100 / colors.Count();
DrawingBrush blackBrush = new DrawingBrush();
DrawingGroup checkersDrawingGroup = new DrawingGroup();
List<SolidColorBrush> brushes = colors;
double location = 0;
for (int i = 0; i < colors.Count(); i++)
{
GeometryDrawing drawing = new GeometryDrawing(brushes[i], null,
new RectangleGeometry(new Rect(location, 0, groupsize, groupsize)));
checkersDrawingGroup.Children.Add(drawing);
location += groupsize;
}
blackBrush.Drawing = checkersDrawingGroup;
swatch.Fill = blackBrush;
swatch.MouseUp += new MouseButtonEventHandler(loadSwatchResources);
ug_Thumbnails.Children.Add(swatch);
You need to use the Rectangle in System.Windows.Shapes when trying to reference a rectangle in WPF. This is specifically for rectangles in WPF and as such is a bit different than the System.Drawing rectangle class. You should be able to cast to this version of rectangle since it derives from FrameworkElement. See http://msdn.microsoft.com/en-us/library/system.windows.shapes.rectangle(v=vs.110).aspx for more info.
Related
I have a project that I need to make an image follow a spline.
I build the spline using Graphics.DrawCurve through an array of Points.
I'm trying to use PointAnimationUsingPath but I can't seem to get it to work. Apparently it doesn't work in C# with Windows form.
Can someone give me a light on how to do this?
Thank you All.
-----EDIT-----
Change to a WPF UserControl as recommend in comments.
Still need some help as the shape does not move exactly following the dots, below my code:
public partial class SplineBox : UserControl
{
Point[] finalPoint;
public SplineBox()
{
InitializeComponent();
}
public void MoveShape(Point[] _path)
{
// Create a NameScope for the page so that
// we can use Storyboards.
NameScope.SetNameScope(this, new NameScope());
// Create the EllipseGeometry to animate.
EllipseGeometry animatedEllipseGeometry =
new EllipseGeometry(new Point(10, 100), 15, 15);
// Register the EllipseGeometry's name with
// the page so that it can be targeted by a
// storyboard.
this.RegisterName("AnimatedEllipseGeometry", animatedEllipseGeometry);
// Create a Path element to display the geometry.
Path ellipsePath = new Path();
ellipsePath.Data = animatedEllipseGeometry;
ellipsePath.Fill = Brushes.Blue;
ellipsePath.Margin = new Thickness(15);
SplineCanvas.Children.Add(ellipsePath);
this.Content = SplineCanvas;
// Create the animation path.
PathGeometry animationPath = new PathGeometry();
PathFigure pFigure = new PathFigure();
pFigure.StartPoint = _path[0];
PolyBezierSegment pBezierSegment = new PolyBezierSegment();
for (int p = 1; p < _path.Length; p++)
{
pBezierSegment.Points.Add(_path[p]);
}
pFigure.Segments.Add(pBezierSegment);
animationPath.Figures.Add(pFigure);
// Freeze the PathGeometry for performance benefits.
animationPath.Freeze();
// Create a PointAnimationgUsingPath to move
// the EllipseGeometry along the animation path.
PointAnimationUsingPath centerPointAnimation = new PointAnimationUsingPath();
centerPointAnimation.PathGeometry = animationPath;
centerPointAnimation.Duration = TimeSpan.FromSeconds(5);
centerPointAnimation.RepeatBehavior = RepeatBehavior.Forever;
// Set the animation to target the Center property
// of the EllipseGeometry named "AnimatedEllipseGeometry".
Storyboard.SetTargetName(centerPointAnimation, "AnimatedEllipseGeometry");
Storyboard.SetTargetProperty(centerPointAnimation,
new PropertyPath(EllipseGeometry.CenterProperty));
// Create a Storyboard to contain and apply the animation.
Storyboard pathAnimationStoryboard = new Storyboard();
pathAnimationStoryboard.RepeatBehavior = RepeatBehavior.Forever;
pathAnimationStoryboard.AutoReverse = true;
pathAnimationStoryboard.Children.Add(centerPointAnimation);
// Start the Storyboard when ellipsePath is loaded.
ellipsePath.Loaded += delegate (object sender, RoutedEventArgs e)
{
// Start the storyboard.
pathAnimationStoryboard.Begin(this);
};
}
public void Paint(ScreenObject _spline)
{
List<Point> points = new List<Point>();
if (true)
{
var spline = _spline;
foreach (System.Windows.Point point in spline.SplineAnchors)
{
Point tempP = new Point((int)point.X, (int)point.Y);
points.Add(tempP);
}
finalPoint = points.ToArray();
//Pen pen = new Pen(Color.FromArgb(255, 0, 0, 255), 1);
//e.Graphics.DrawCurve(pen, finalPoint);
foreach (Point p in finalPoint)
{
// Create a red Ellipse.
Ellipse myEllipse = new Ellipse();
// Create a SolidColorBrush with a red color to fill the
// Ellipse with.
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
// Describes the brush's color using RGB values.
// Each value has a range of 0-255.
mySolidColorBrush.Color = Color.FromArgb(255, 100, 255, 0);
myEllipse.Fill = mySolidColorBrush;
myEllipse.StrokeThickness = 2;
myEllipse.Stroke = Brushes.Black;
// Set the width and height of the Ellipse.
myEllipse.Width = 10;
myEllipse.Height = 10;
myEllipse.Margin = new Thickness(p.X - 5, p.Y - 5, 0, 0);
//e.Graphics.DrawRectangle(pen, new Rectangle(p.X - 5, p.Y - 5, 10, 10));
//e.Graphics.FillRectangle(Brushes.Red, new Rectangle(p.X - 5, p.Y - 5, 10, 10));
SplineCanvas.Children.Add(myEllipse);
}
}
}
}
I am trying to display different shapes on Content Presenter in wpf, I am able to show Rectangle but Line object is not getting populated, Can anyone help me with this
Line r = new Line();
r.SetValue(Canvas.TopProperty, 50.0);
r.SetValue(Canvas.LeftProperty, 10.0);
r.X1 = 50;
r.Y1 = 50;
r.X2 = 150;
r.Y2 = 150;
r.Width = 200;
r.StrokeThickness = 5.0;
r.Fill = new SolidColorBrush(Colors.Green);
ContentComponent.Content = r;
You should set the Stroke property to a Brush:
r.Stroke = Brushes.Green;
Note that there is no reason to create a new green brush using new SolidColorBrush(Colors.Green) instead of using the static Green property of the Brushes class.
From within MainWindow ctor :
for(var i = 0; i <5; i++)
{
var button = new Button {};
button.LayoutTransform = new RotateTransform(i * 10);
button.Width = 300;
button.Height = 300;
TempCanvas.Children.Add(button);
}
This produces the following:
Please can someone explain why this is happening. I am expecting the 5 buttons to be rotated through the same point.
I did not want to RenderTransform as the graphics that I will be rendering would be drawn outside of the parent and not reflected in the measure.
The Canvas is the issue, unlike other contains it is not constrained in its physical size, it stretches out to infinity in all directions. Therefore it's rotation origin is not the canvas.width/2 by canvas.height/2.
If you repeat your code in a grid or dockpanel you will get the required result.
Do you want something like this:
Code:
for (var i = 0; i < 5; i++)
{
var button = new Button { };
//button.LayoutTransform = new RotateTransform(i * 10);
button.RenderTransform = new RotateTransform(i * 10);
button.Width = 300;
button.Height = 300;
button.Margin = new Thickness(200, 0, 0, 0);
TempCanvas.Children.Add(button);
}
I'm trying to draw a row of rectangles across my Canvas. When I run the following code, I only get one rectangle, even though my canvas element says it has 12 children.
Dimensions is a class with 2 integer properties, Height and Width. The canvas I am drawing this is on 400px by 600px.
Dimensions windowDimensions = new Dimensions()
{
Width = (int)cvsGameWindow.Width,
Height = (int)cvsGameWindow.Height
};
//init rectangles
for (int i = 0; i < windowDimensions.Width; i+=50)
{
Rectangle rect = new Rectangle(); //create the rectangle
rect.StrokeThickness = 1; //border to 1 stroke thick
rect.Stroke = _blackBrush; //border color to black
rect.Width = 50;
rect.Height = 50;
rect.Name = "box" + i.ToString();
Canvas.SetLeft(rect,i * 50);
_rectangles.Add(rect);
}
foreach (var rect in _rectangles)
{
cvsGameWindow.Children.Add(rect);
}
and the private members declared at the top of my code:
private SolidColorBrush _blackBrush = new SolidColorBrush(Colors.Black);
private SolidColorBrush _redBrush = new SolidColorBrush(Colors.Red);
private SolidColorBrush _greenBrush = new SolidColorBrush(Colors.Green);
private SolidColorBrush _blueBrush = new SolidColorBrush(Colors.Blue);
private List<Rectangle> _rectangles = new List<Rectangle>();
This is the culprit:
Canvas.SetLeft(rect,i * 50);
On the first loop, with i=0, you're setting Canvas.Left = 0; Since your for loop is doing i+=50, on the second loop i will be 50, so you'll be setting Canvas.Left = 2500. You said your Canvas is 400x600, so your rectangles are off-screen.
The simplest fix: use Canvas.SetLeft(rect, i) - since i is increasing in increments of 50.
I'm coding in Microsoft Visual Studio 2010 Express for Windows Phone. I need to add a point onto a Canvas, but I can't...
for (float x = x1; x < x2; x += dx)
{
Point poin = new Point();
poin.X = x;
poin.Y = Math.Sin(x);
canvas1.Children.Add(poin);
}
Studio says:
Error 2 Argument 1: cannot convert from 'System.Windows.Point' to 'System.Windows.UIElement'
My question is: how do I add a point onto a Canvas?
From your code snippet I assume you're trying to draw a curve. To do this, you can look into GraphicsPath. Instead of drawing individual points, you can use the points as coordinates, which you connect through lines. Then, in your code, you can create a GraphicsPath using the AddLine method.
This could then be drawn onto a bitmap, for example.
EDIT
Sample (not tested):
GraphicsPath p = new GraphicsPath();
for (float x = x1; x < x2; x += dx)
{
Point point = new Point();
point.X = x;
point.Y = Math.Sin(x);
Point point2 = new Point();
point2.X = x+dx;
point2.Y = Math.Sin(x+dx);
p.AddLine(point, point2);
}
graphics.DrawPath(p);
Another way would be to use the WPF Path class, which would work about the same, but is a real UI element which you can add to the children of a Canvas.
EDIT
People have pointed out that the above code is Windows Forms code. Well, here's what you can do in WPF:
myPolygon = new Polygon();
myPolygon.Stroke = System.Windows.Media.Brushes.Black;
myPolygon.Fill = System.Windows.Media.Brushes.LightSeaGreen;
myPolygon.StrokeThickness = 2;
myPolygon.HorizontalAlignment = HorizontalAlignment.Left;
myPolygon.VerticalAlignment = VerticalAlignment.Center;
PointCollection points = new PointCollection();
for (float x = x1; x < x2; x += dx)
{
Point p = new Point(x, Math.Sin(x));
points.Add(p);
}
myPolygon.Points = points;
canvas1.Children.Add(myPolygon);
If it is 'just a single point you want to add, you can add a tiny rectangle or ellipse to the canvas.
If you want to set a lot of points or a couple points many times, I suggest you create an array of pixel data (colors) and write those to a WriteableBitmap
The Point you used is not a UIElement but a struct, please use Line instead.
Line lne = new Line();
lne.X1 = 10;
lne.X2 = 11;
lne.Y1 = 10;
lne.Y2 = 10;
canvas1.Children.Add(lne);
You get the idea...
Edit
changed:
lne.X2 = 10 to lne.X2 = 11
As per the error, the children of the Canvas control must be derivatives of the System.Windows.UIElement class: System.Windows.Point is not. To achieve what you are doing, you would be best looking into using the geometry within WPF. See here for an article on how to do so.
Try adding a ellipse
Ellipse myEllipse = new Ellipse();
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
mySolidColorBrush.Color = Color.FromArgb(255, 255, 255, 0);
myEllipse.Fill = mySolidColorBrush;
myEllipse.StrokeThickness = 2;
myEllipse.Stroke = Brushes.White;
myEllipse.Width = 200;
myEllipse.Height = 100;
Canvas.SetTop(myEllipse,50);
Canvas.SetLeft(myEllipse,80);
myCanvas.Children.Add(myEllipse);