Is there a way to add additional values to the rectangle struct? - c#

I want to add additional values to a rectangle. Like a "Name" string for example.
Something like this:
Rectangle MyRectangle = new Rectangle(Y, X, Width, Height, Name)
Is this possible?

There is two overload constructor function in Rectangle class.
public Rectangle(Point location, Size size);
public Rectangle(int x, int y, int width, int height);
But there isn't a constructor function parameter new Rectangle([int], [int], [int], [int], [string]) in Rectangle class.
You can try to use composite public Rectangle rect { get; set; } property in the class.
Then use constructor function to set Rectangle object and Name
public class CustomerRectangle
{
public Rectangle Rect { get; set; }
public string Name { get; set; }
public CustomerRectangle(int llx, int lly, int urx, int ury,string name)
{
Rect = new Rectangle(llx, lly, urx, ury);
Name = name;
}
}
then you can use
CustomerRectangle MyRectangle = new CustomerRectangle (Y, X, Width, Height, Name);
//MyRectangle.Name; use Name property
//MyRectangle.Rect; use Rectangle

I assume you are using a constructor from the System.Drawing namespace:
https://learn.microsoft.com/en-us/dotnet/api/system.drawing.rectangle?view=netframework-4.7.2
It is not possible to add an extra field to that structure. What you can do is create your own class or structure which does contain more .
public class NamedRectangle
{
public string Name { get; set; }
public double X { get; set; }
public double Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public NamedRectangle(double x, double y, double width, double height, string name)
{
Name = name;
X = x;
Y = y;
Width = width;
Height = height;
}
}

I've seen others have contributed good examples, but in case of Cannot inherit from sealed type error, following example might help you:
public class myRectangle
{
private Rectangle newRectangle = new Rectangle();
private string name;
public myRectangle Rectangle(Int32 Y, Int32 X, Int32 Height, Int32 Width, string name )
{
newRectangle.Y = Y;
newRectangle.X = X;
newRectangle.Height = Height;
newRectangle.Width = Width;
this.name = name;
return this;
}
}

Related

I cannot set and call value using setter and getter

Learning Setter and Getter
I am making a console log app where I create a Box class and make an object and set values: width, height, and length using setter and getter. I was referencing an solution on github, but I haven't make it work yet. I don't know where I made mistake.
My Code
using System;
namespace ClassDemo2
{
class Box
{
private double _width;
private double _height;
private double _length;
public double Width
{
get { return _width; }
set { this._width = Width; }
}
public double Height
{
get { return _height; }
set { this._height = Height; }
}
public double Length
{
get { return _length; }
set {this._length = Length; }
}
public double volume()
{
return Width * Height * Length;
}
}
public class Program
{
static void Main(string[] args)
{
Box box = new Box();
//Set value
box.Width = 12;
box.Height = 12;
box.Length = 12;
//Get value
double width = box.Width;
double height = box.Height;
double length = box.Length;
Console.WriteLine("Box properties");
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Height: {0}", height);
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Volume: {0}", box.volume());
}
}
}
Console Window
The setters in the Box class aren't doing anything. The setters aren't assigning a value to the private fields in the Box class.
You may as well remove the fields altogether and use auto-implemented properties.
For example:
class Box
{
public double Width { get; set; }
public double Height { get; set; }
public double Length { get; set; }
public double Volume()
{
return Width * Height * Length;
}
}
class Box
{
public double Width { get; set; }
public double Height { get; set; }
public double Length { get; set; }
public double volume()
{
return Width * Height * Length;
}
}
Use Auto-Implemented Properties (https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/auto-implemented-properties)

Oxyplot: AreaSeries ItemSource with custom DataPoints

I am using the AreaSeries in Oxyplot to graph a range between two points and would like the Tracker to display both of them when hovered. I achieved making the Tracker display custom properties with other series by creating a custom class for the DataPoints and changing the TrackerFormat accordingly. Here is an example:
public class CommentPoint : IScatterPointProvider
{
public CommentPoint(double x, double y, string text)
{
X = x; Y = y; Text = text;
}
public double X, Y;
public string Text { get; set; }
public ScatterPoint GetScatterPoint()
{
return new ScatterPoint(X, Y);
}
}
And the TrackerFormat:
Series.TrackerFormatString = "{2}\n{Text}";
However, this only works when adding an array of the new points as the ItemSource of the series. With Line/ScatterSeries it's easy, since they require just a list of points. But an AreaSeries requres 2 points to be graphed.
I tried adding a 2d array of these custom points as the ItemSource:
public class AreaPoint : IDataPointProvider
{
public AreaPoint(double x, double y, double y2)
{
X = x; Y1 = y; Y2 = y2;
}
public double X { get; set; }
public double Y1 { get; set; }
public double Y2 { get; set; }
public DataPoint GetDataPoint()
{
return new DataPoint(X, Y1);
}
}
So basically:
AreaPoint[,] points = new AreaPoint[2,amount.Count]
AreaPoint[0,i] = new AreaPoint(x,y,y2);
....
Series.ItemSource = points;
That doesn't work and I recieved an error "Is not a one-dimentional array".
Next I tried adding the points directly via the GetDataPoint method:
Series.Points.Add(new AreaPoint(x,y,y2).GetDataPoint());
Series.Points2.Add(new AreaPoint(x2,y2,y3).GetDataPoint());
Series.TrackerFormatString = "{2}\n{4}\n{Y2}";
This works in that the AreaSeries is being plotted correctly, but the Tracker won't display my custom properties.
So I suppose my question is, how can I add a custom ItemSource to an AreaSeries?
You can just add X2, Y2 fields to your custom point class and set DataField properties in your AreaSeries.
public class AreaPoint : IDataPointProvider
{
public AreaPoint(double x, double y, double x2, double y2, string customValue)
{
X = x;
Y = y;
X2 = x2;
Y2 = y2;
CustomValue = customValue;
}
public double X { get; set; }
public double Y { get; set; }
public double X2 { get; set; }
public double Y2 { get; set; }
public string CustomValue { get; set; }
}
...
series = new AreaSeries();
series.DataFieldX = "X";
series.DataFieldY = "Y";
series.DataFieldX2 = "X2";
series.DataFieldY2 = "Y2";
series.TrackerFormatString = "{0}\n{1}: {2}\n{3}: {4}" +
"\nMy custom value: {CustomValue}"

Linking instances of two classes together

Programming newbie here and I've been breaking my head over this for several hours now.
I can make a coordinate object but then I want to make a dot object that can access the coordinate fields from a Coordinate object. How do I "link" these two classes together? And do you have any recommendations for good YouTube videos that explain what I'm missing here? Thanks!
class Coordinate
{
public int X { get; private set; } = 0;
public int Y { get; private set; } = 0;
public Coordinate(int x, int y)
{
x = X;
y = Y;
}
}
class Dot
{
public string color { get; set; }
public Dot(string color, Dot dot)
{
this.Color = color;
}
}
class Program
{
static void Main(string[] args)
{
Coordinate coor1 = new Coordinate(2, 3);
Dot dot1 = new Dot("Blue", coor1);
}
Here is what you are searching for a "linking" your classes. In object-oriented programming this is called composition.
That way you can use functionality and data of Coordinate-instance inside your Dot class.
class Coordinate
{
public int X { get; private set; }
public int Y { get; private set; }
public Coordinate(int x, int y)
{
X = x;
Y = y;
}
}
class Dot
{
public Coordinate coord { get; private set; }
public string color { get; set; }
public Dot(string color, Coordinate coord)
{
this.color = color;
this.coord = coord;
}
}
class Program
{
static void Main(string[] args)
{
Coordinate coor1 = new Coordinate(2, 3);
Dot dot1 = new Dot("Blue", coor1);
Console.WriteLine(dot1.coord.X);
}
}
Note: I also fixed possible typo in Coordinate-constructor (setting X=x and Y=y..)

Creating multiple / multinode properties in class

I would like to understand and make my own classes in the way like the common rectangle:
Rectangle r1 = new Rectangle();
Size s = r1.Size;
int size = r1.Size.Width;
I don't want to use methods, just simple property values.
public partial class Rectangle
{
private Size _size;
public Size Size
{
get { return _size; }
set { _size = value; }
}
}
So how to create the Width, Height, etc. properties?
And if i would like to create longer chain? e.g.:
r1.Size.Width.InInches.Color.
etc.
Probably you'll find yourself saying: I knew it.
Class properties can be associations with other classes:
public class Size
{
public Size(double width, double height)
{
Width = width;
Height = height;
}
public double Width { get; }
public double Height { get; }
}
Now you'll be able to get rectangle's size as follows: rect1.Size.Width.
About providing the size unit, I wouldn't create an InInches property, but I would create an enumeration:
public enum Unit
{
Inch = 1,
Pixel
}
...and I would add a property to Size as follows:
public class Size
{
public Size(double width, double height, Unit unit)
{
Width = width;
Height = height;
Unit = unit;
}
public double Width { get; }
public double Height { get; }
public Unit Unit { get; }
}
...and if you need to perform conversions, you could easily implement them in Size too:
public class Size
{
public Size(double width, double height, Unit unit)
{
Width = width;
Height = height;
Unit = unit;
}
public double Width { get; }
public double Height { get; }
public Unit Unit { get; }
public Size ConvertTo(Unit unit)
{
Size convertedSize;
switch(unit)
{
case Unit.Inch:
// Calc here the conversion from current Size
// unit to inches, and return
// a new size
convertedSize = new Size(...);
break;
case Unit.Pixel:
// Calc here the conversion from current Size
// unit to pixels, and return
// a new size
convertedSize = new Size(...);
break;
default:
throw new NotSupportedException("Unit not supported yet");
break;
}
return convertedSize;
}
}
What you call chain is what in object-oriented programming is called composition.
Thus, you can associate Size with other class, and associate another class to the other one, and so on...

Exchanging variables between 2 classes

Whenever I call the method Draw in Sprite, it won't draw it because X, Y, Width and Height are 0. :(
code:
class Sprite
{
protected int Y;// { get; set; }
protected int X;// { get; set; } { get; set; }
protected int Width;// { get; set; } { get; set; }
public int Height;// { get; set; } { get; set; }
protected Image image;// { get; set; } { get; set; }
public Sprite()
{
}
public void Draw(Graphics drawArea)
{
Image sImage = Image.FromFile("alien.jpg");
drawArea.Clear(Color.White);
drawArea.DrawImage(sImage, X, Y, Width, Height);
}
}
class User:Sprite
{
public User()
{
}
public User(int width, int height, int userWidth, int userHeight)
{
Sprite sprite = new Sprite();
Image UserImage = Image.FromFile("alien.jpg");
X = width;
Y = height;
Width = userWidth;
Height = userHeight;
image = UserImage;
}
}
ps: sprite.Draw is declared in another method in another class, but that all should work just fine.
Thanks for helping and probably saving me hours of time :)
Nick
EDIT
here is the subclass which gives the parameter and other stuff.
Alien mAlien;
User mUser;
protected int mLevel;
public gameLogic()
{
}
public gameLogic(int width, int height, int level)
{
mUser = new User(width / 2, height - 30, 30, 30);
mAlien = new Alien(width / 2, 5, 30, 30, "alien.jpg", 10 * level);
mLevel = level;
}
public void drawAll(Graphics drawArea)
{
Sprite sprite = new Sprite();
sprite.Draw(drawArea);
}
Im sorry for all these errors that'll probably occur, Im a new student :)
Try this:
public User(int width, int height, int userWidth, int userHeight)
{
Sprite sprite = new Sprite();
Image UserImage = Image.FromFile("alien.jpg");
sprite.X = width;
sprite.Y = height;
sprite.Width = userWidth;
sprite.Height = userHeight;
sprite.image = UserImage;
}
In order to access the fields of the sprite, you have to specify which Sprite object you are modifying. This is done by writing the name of the variable followed by .
EDIT: Just realized that there is another problem - your User class is inheriting from the Sprite class. Apparently your users are sprites, according to the comments, so you'll want to never instantiate a Sprite, and just use the User class instead:
class User:Sprite
{
public User(int width, int height, int userWidth, int userHeight)
{
Image UserImage = Image.FromFile("alien.jpg");
X = width;
Y = height;
Width = userWidth;
Height = userHeight;
image = UserImage;
}
}
Then instead of calling draw on a sprite in the other file, use the following:
User user = new User(x, y, width, height)
...
user.draw();
The key here is to make sure you are using new User... and not new Sprite - even if you are assigning to a Sprite variable e.g. Sprite s = new User(...);.
Then just make sure you call draw on the same object - the user.draw line. If you want to check that you're doing it right, try making Sprite abstract - abstract class Sprite - that way there will be compile errors if you try to instantiate Sprite instead of User.
EDIT 2: Ok, all you really need to do is change your calling code:
public void drawAll(Graphics drawArea)
{
mUser.draw(drawArea);
mAlien.draw(drawArea);
}
You are missing trailing '}' for both your classes, Sprite and User. Second you should call the base-Constructor in User's constructor:
public User(int width, int height, int userWidth, int userHeight)
: base(width, height, userWidth, userHeight, Image.FromFile("alien.jpg"))
{
}
Also you need to create a constructor for your base class which accepts these parameters.

Categories

Resources