Add visual to Custom UI Object - c#

I have a Custom UIElement I created below.
class ClickItem : UIElement
{
public ClickItem()
{
}
public ClickItem(Color color)
{
this.Color = color;
Ellipse _e = new Ellipse();
_e.Fill = new SolidColorBrush(this.Color);
_e.StrokeThickness = 1;
_e.Stroke = Brushes.Black;
_e.Width = 10;
_e.Height = 10;
this.Plotter = _e;
}
public Point CenterPoint { get; set; }
public Ellipse Plotter { get; set; }
public Color Color { get; set; }
}
How do I make the Plotter Ellipse the visual for the UIElement so when I add a ClickItem to a canvas, the `Plotter' shows up.
Canvas canvas = new Canvas();
ClickItem clickItem = new ClickItem(Colors.Red);
canvas.Add(clickItem);
I can do this but I don't know how to get the ClickItem from this if I click on it.
canvas.Add(clickItem.Plotter);

I think you should inherit from user control, or some other relevant lower class, and add the ellipse as a child of your ClickItem.

Related

How to calculate area using Open closed principle C#

I am working with Open Closed principle of SOLID in C#. I have abstract class Shape which i want to used to calculate the area of different shapes. How to call areaCalculator class and how to pass different shapes. Here is my code.
public abstract class Shape
{
public abstract double Area();
}
public class Rectangle : Shape
{
public double Height { get; set; }
public double Width { get; set; }
public override double Area()
{
return Height * Width;
}
}
public class AreaCalculator
{
public double TotalArea(Shape[] shapes)
{
double area = 0;
foreach (var objShapes in shapes)
{
area += objShapes.Area();
}
return area;
}
}
I want to call areaCalculator class to calculate the area.
AreaCalculator _obj = new AreaCalculator();
Shape[] _shapes = new Shape[2];
var _result = _obj.TotalArea(_shapes);
Console.WriteLine(_result);
Console.ReadLine();
You need to create the rectangle objects and set their height and width for the calculation. If not the _shapes list is empty. Find below a sample of working code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ShapesStacjOverflow {
public abstract class Shape {
public abstract double Area();
}
public class Rectangle : Shape {
public double Height { get; set; }
public double Width { get; set; }
public override double Area() {
return Height * Width;
}
}
public class AreaCalculator {
public double TotalArea(Shape[] shapes) {
double area = 0;
foreach (var objShapes in shapes) {
area += objShapes.Area();
}
return area;
}
}
class Program {
static void Main(string[] args) {
AreaCalculator _obj = new AreaCalculator();
Shape[] _shapes = new Shape[2];
Rectangle rectangle1 = new Rectangle {
Width = 2,
Height = 3
};
Rectangle rectangle2 = new Rectangle {
Width = 1,
Height = 1
};
_shapes[0] = rectangle1;
_shapes[1] = rectangle2;
var _result = _obj.TotalArea(_shapes);
Console.WriteLine(_result);
Console.ReadLine();
}
}
}
Returning 7 as a result.
If you want to create other child shapes, those should override the Area() method, so for each of the objects created in the list, the corresponding Area() method would be applied.
Hope that helps.

Draw a shape on a canvas in a new window C#

I am looking for a way to draw a simple shape on a canvas with the shape being made in another class ShapeManager. This ShapeManager decides what shape it is and assigns a color to it coming from ColorManager.
I apologize in advance for the long code, this is my first post and I am still just learning C# and OOP in general.
Canvas Window
A window with a canvas on it (cvs_Drawing). Should place a shape it gets from CanvasManager.ShapeManager.CreateNewShape(), but throws a NullReference.
public partial class CanvasWindow : Window
{
public string CanvasName { get; set; }
public CanvasManager CanvasManager { get; set; }
public CanvasWindow(string name)
{
InitializeComponent();
CanvasManager= new CanvasManager();
CanvasName = name;
this.Title = CanvasName;
}
//Click event to draw the chosen shape on canvas
private void cvs_Drawing_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
try
{
Shape shapeDrawing = CanvasManager.ShapeManager.CreateNewShape();
Point location = e.GetPosition(cvs_Drawing);
Canvas.SetTop(shapeDrawing, location.Y);
Canvas.SetLeft(shapeDrawing, location.X);
cvs_Drawing.Children.Add(shapeDrawing);
}
//catch block here
CanvasManager
Creates CanvasWindows and provides interaction between CanvasWindow and ShapeManager. Multiple CanvasWindows is normally a possibility.
public CanvasWindow CanvasWindow { get; set; }
public MainWindow MainWindow { get; set; }
public ShapeManager ShapeManager { get; set; }
//Constructors
public CanvasManager(MainWindow w)
{
MainWindow = w;
ShapeManager = new ShapeManager(w);
}
public CanvasManager() { }
//Add a brand new canvas
public CanvasWindow CreateNewCanvas(string name)
{
CanvasWindow = new CanvasWindow(name);
return CanvasWindow;
}
ShapeManager
Creates Shapes needed for CanvasWindow
public MainWindow Window { get; set; }
public Shape NewShape { get; set; }
public ColorManager ColorManager { get; set; }
public List<string> ListShapes { get; set; } = new List<string>();
public ShapeManager(MainWindow w)
{
Window = w;
ListShapes.Add("Ellipse");
ListShapes.Add("Rectangle");
ColorManager = new ColorManager();
}
public ShapeManager() { }
#region Shape Creation
public Shape CreateNewShape()
{
Color newShapeColor = ColorManager.CreateNewColor();
if (Window.cb_Shapes.SelectedItem.ToString() == "Ellipse")
{
NewShape = new Ellipse
{
Width = Int32.Parse(Window.tb_Width.Text),
Height = Int32.Parse(Window.tb_Height.Text),
Fill = new SolidColorBrush(newShapeColor)
};
return NewShape;
}
else
{
NewShape = new Rectangle
{
Width = Int32.Parse(Window.tb_Width.Text),
Height = Int32.Parse(Window.tb_Height.Text),
Fill = new SolidColorBrush(newShapeColor)
};
return NewShape;
}
}
ColorManager
Creates the color for the shape that was created in ShapeManager.
public MainWindow Window { get; set; }
public Color NewColor { get; set; }
//Constructors
public ColorManager(MainWindow w)
{
Window = w;
}
//public ColorManager(){}
//Add new color method
public Color CreateNewColor()
{
NewColor = new Color
{
A = 255,
R = Byte.Parse(Window.tb_RedValue.Text),
G = Byte.Parse(Window.tb_GreenValue.Text),
B = Byte.Parse(Window.tb_BlueValue.Text)
};
return NewColor;
}
TL;DR. I can't create a shape on the canvas, always get a NullReference every time I click on the canvas.
Your code has an error here
public CanvasManager(){ ShapeManager = new ShapeManager(MainWindow); }
// CanvasManager.cs , Line 33
you passed MainWindow, which is null
and it comes from here
public CanvasManager CanvasManager { get; set; } = new CanvasManager();
// CanvasWindow.xaml.cs, Line 28
You can correct your code like this:
// in CanvasWindow.xaml.cs, Line 28
public CanvasWindow(string name, MainWindow mainWindow)
{
InitializeComponent();
**CanvasManager = new CanvasManager(mainWindow);**
CanvasName = name;
//ShapeManager = new ShapeManager();
this.Title = CanvasName;
...
...
...
// NewDrawingWindow.xaml.cs, Line 47
CanvasWindow canvasWindow = new CanvasWindow(tb_Drawing_Name.Text, Window);
// CanvasManager.cs, Line 38
CanvasWindow = new CanvasWindow(name, MainWindow);

How to get Speed from GeoCoordinate

I am using GMap.Net to add ellipses as marker on map at runtime. ToolTip property of each ellipse is set to display Time and Speed when Added. Instead of number as speed I get NaN always.
On Timer's elapsed event Addellipse method is called -
void Addellipse(object sender, ElapsedEventArgs e)
{
App.Current.Dispatcher.Invoke(() =>
{
getInfo = GetLocationProperty();
Ellipse ellipse = new Ellipse()
{
Fill = Brushes.Black,
ToolTip = getInfo.CurrentTime + "\n" + getInfo.CurrentSpeed,
Height = 7,
Width = 7
};
GMapMarker marker = new GMapMarker(getInfo.CurrentPosition)
{
Shape = ellipse,
ZIndex = int.MaxValue
};
MapControl.Markers.Add(marker);
MapControl.Position = getInfo.CurrentPosition;
});
}
GetLocationProperty returns ToolTipInfo
ToolTipInfo GetLocationProperty()
{
coord = watcher.Position.Location;
if (!coord.IsUnknown)
{
returnlatlon.Lat = coord.Latitude;
returnlatlon.Lng = coord.Longitude;
tooltipInfo.CurrentPosition = returnlatlon;
tooltipInfo.CurrentTime = DateTime.Now.ToShortTimeString();
tooltipInfo.CurrentSpeed = coord.Speed.ToString();
}
return tooltipInfo;
}
here is the ToolTipInfo
public class ToolTipInfo
{
public PointLatLng CurrentPosition { get; set; }
public string CurrentTime { get; set; }
public string CurrentSpeed { get; set; }
}
and my watcher is initialized in this way in constructor
watcher = new GeoCoordinateWatcher();
watcher.TryStart(true, TimeSpan.FromMilliseconds(2000));
How can I get speed?

Serialize Media and Shapes objects

I want to serialize my object as binary or xml.
I used this method to serialize my object. but it gives error : System.Windows.Media.SolidColorBrush not serializable.
My object contains Grid, Ellipse, SolidColorBrush objects.
How can I serialize these objects?
You need to create a SerializableBrush class of your own which has constructors taking SolidBrush etc and also a ToBrush method to reconstruct the GDI+ brushes..
The same goes for most other GDI+ objects and structures like Color, Pen etc, some of which, like Color you will even need for the SerializableBrush class..
Adorn it with the [Serializable] attribute!
A simple serializable Color class:
[Serializable]
public class SerColor
{
public byte Red { get; set; }
public byte Green { get; set; }
public byte Blue { get; set; }
public byte Alpha { get; set; }
public SerColor() { }
public SerColor(Color c)
{ Red = c.R; Green = c.G; Blue = c.B; Alpha = c.A; }
static public Color Color(SerColor c)
{ return System.Drawing.Color.FromArgb(c.Alpha, c.Red, c.Green, c.Blue); }
}
'And a simple serializable SolidBrush class:
[Serializable]
public class SerSolidBrush
{
public SerColor sColor { get; set; }
public SerSolidBrush() { }
public SerSolidBrush(Color c)
{
sColor = new SerColor(c);
}
public SerSolidBrush(SolidBrush b)
{
sColor = new SerColor(b.Color);
}
public SolidBrush SolidBrush()
{
Color c = SerColor.Color(sColor);
return new System.Drawing.SolidBrush(c);
}
static public SolidBrush SolidBrush(SerSolidBrush b)
{
Color c = SerColor.Color(b.sColor);
return new System.Drawing.SolidBrush(c);
}
}
And a small test bed:
SolidBrush brush = new SolidBrush(Color.Red);
SerSolidBrush sBrush = new SerSolidBrush(brush);
XmlSerializer xs = new XmlSerializer(sBrush.GetType());
using (TextWriter tw = new StreamWriter(#"d:\xmlBrush.xml"))
{
xs.Serialize(tw, sBrush);
tw.Close();
}
SerSolidBrush sBrush2 = null;
using (TextReader tr = new StreamReader(#"d:\xmlBrush.xml"))
sBrush2 = (SerSolidBrush) xs.Deserialize(tr);
SolidBrush newBrush = sBrush2.SolidBrush();
This is the resulting xml file ((no idead how to insert xml text in an SO answer properly)):
I hope this shows how to do it; note that SolidBrush is a very simple class with only one property. Pen and most others will be more complicated if you want to support all properties..
Note that simple built-in enums, like LineJoin etc are serializable, so you can simply add the proerties and everything works just fine. To demostrate here is a rather incomplete serilizable Pen class. You will want to add several other properties..:
[Serializable]
public class SerPen
{
public SerColor sColor { get; set; }
public float width { get; set; }
public LineJoin lineJoin { get; set; }
// constructors
public SerPen() { width = 1f; }
public SerPen(Color c, float w)
{
sColor = new SerColor(c);
width = w;
}
public SerPen(Pen p)
{
sColor = new SerColor(p.Color);
width = p.Width;
lineJoin = p.LineJoin;
}
// re-constructors
public Pen Pen ()
{
Color c = SerColor.Color(sColor);
Pen pen = new System.Drawing.Pen (c, width);
pen.LineJoin = lineJoin;
return pen;
}
static public Pen Pen (SerPen p)
{
Color c = SerColor.Color(p.sColor);
Pen pen = new System.Drawing.Pen (c, p.width);
pen.LineJoin = p.lineJoin;
return pen;
}
}

How to make size of polygon equal to size of window?

I have created a custom control( polygon) using windows form application. The code is:
public partial class shape7 : Control
{
public Point p1 { get; set; }
public Point p2 { get; set; }
public Point p3 { get; set; }
public Point p4 { get; set; }
public shape7()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
GraphicsPath _outline = new GraphicsPath();
Point[] p = new Point[4]{new Point(p1.X,p1.Y),
new Point(p2.X,p2.Y),
new Point(p3.X,p3.Y),
new Point(p4.X,p4.Y)};
_outline.AddPolygon(p);
this.Region = new Region(_outline);
}
where
p1 = 0,0
p2 = 100,0
p3 = 120,50
p4 = 20,0
Its giving me control like this:
as you can see in my Form1 the size of outer dotted window is not equal to my object polygon.
I want that if in increase the size of window than the object size should also get increase.
Please suggest how to do this.
Also i Want the default color of this object to black or blue.

Categories

Resources