There is a task: "Using dynamic objects and virtual methods, develop a program for displaying and changing the color of the frame consisting of two squares"

I created the MyRectangles class, which draws rectangles of the same color, and the RedRectangles class, which draws the same squares but in a different color. But for some reason nothing is drawn. How to correctly implement polymorphism for my example?

public partial class Form1 : Form { private int _rectangleXPosition; public Form1() { InitializeComponent(); MyRectangles rectangles = new MyRectangles(); rectangles.OnPaint(); } private void button1_Click(object sender, EventArgs e) { } } class MyRectangles : Form { public virtual void OnPaint() { Graphics dc = CreateGraphics(); dc.DrawRectangle(Pens.Black, 5, 5, 750, 400); dc.DrawRectangle(Pens.Black, 10, 10, 740, 380); } } class RedRectangles : MyRectangles { public override void OnPaint() { Graphics dc = CreateGraphics(); dc.DrawRectangle(Pens.Red, 5, 5, 750, 400); dc.DrawRectangle(Pens.Red, 10, 10, 740, 380); } } 
  • And where should it be drawn then? The Graphics object somewhere else needs to be output the same. And, here you do not need inheritance - just the color property of the class Rectangles - Sergey
  • Must be displayed on the form. According to the task I need to implement the output via virtual methods - MrStacky
  • It should be displayed this way - so you form a bitmap, output it in some image on the form, or do you think that it will draw everything by itself with a wave of a rod? - Sergey
  • It is not drawn because instead of drawing you create a new form and call a drawing method for it. It is drawn, but not in your window, but in a hidden one, since You do not call the Show method on a new form. I doubt that this is what you wanted to achieve, better describe in simple words what you want to do, without terminology that you, apparently, do not fully understand. Method overloading is also polymorphism, only of a different kind. - rdorn
  • Added to the description of the question, the task that I need to do. In fact, I want to make the MyRectangles class, which draws black squares on the form, inherit from it another class with a different color of squares and display squares of different colors depending on the object that is called - MrStacky

1 answer 1

Ok, to start a mistake or why

But for some reason nothing is drawn

I leave only the necessary code from yours with my comments:

 public partial class Form1 : Form { public Form1() { InitializeComponent(); //создаете новый объект наследника формы, но этого не достаточно //для его отображения MyRectangles rectangles = new MyRectangles(); //вызываете метод OnPaint у новой формы, но этого тоже не достаточно, //для того, чтобы окно появилось на экране rectangles.OnPaint(); } ... } class MyRectangles : Form //наследуетесь от формы (для простоты, от окна) { ... } class RedRectangles : MyRectangles //продолжаете наследоваться от формы { ... } 

To display the created MyRectangles object, you need to call the Show() method on it, but this does not solve your problem, as this will lead to the opening of an additional window, and I strongly doubt that this is what you need. At the same time, even if you open this new window, then nothing will be drawn in it either, since the signature of your OnPaint() method does not match the signature of the original method that is automatically called, which means someone will have to call it. .

I don’t know what exactly the author of the assignment wanted to say, and, all the more, I wanted to get out of you (I’d tear my hands off for this wording of educational assignments), so let's go the simplest, but correct, in terms of the chosen platform, way.

You will not need additional classes, everything has already been invented before you, you just need to use it correctly, for example:

 public partial class Form1 : Form { //добавим поле для хранения цвета рамки со значением по-умолчанию private Color _boderColor = Color.Black; //переопределяем виртуальный метод формы OnPaint //именно он вызывается автоматически для отрисовки содержимого формы. override protected void OnPaint(PaintEventArgs e) { //вызываем оригинальный метод предка, чтобы не потерять базовую функциональность base.OnPaint(e); //готовим рамку с заданными параметрами GraphicsPath gp = new GraphicsPath(); gp.AddRectangle(new Rectangle(5, 5, 750, 400)); gp.AddRectangle(new Rectangle(10, 10, 740, 380)); //При использовании разных цветов для контура рамки и заливки //сначала закрашиваем рамку e.Graphics.FillPath(new SolidBrush(_boderColor), gp); //потом рисуем рамку e.Graphics.DrawPath(new Pen(_boderColor), gp); } public Form1() { //Конструктор не трогаем, без крайней необходимости InitializeComponent(); } ... } 

Similar to color, you can parametrize the thickness of the frame, the color of the frame fill, the offset from the edge of the form, and other parameters you want to control when drawing. Now it remains to add a button to the form, in the handler of which we call ColorDialog to select a color and write it in the _boderColor field. The main thing, after choosing a color, do not forget to call the Refresh() form method, so that the form is redrawn and the color change is reflected in the frame.

I also advise you to subscribe to the event of the ClientSizeChanged form, and force Refresh() in it to prevent artifacts from occurring when the window is resized.

And one more thing that you will surely forget to tell you about, read about the Control.ClientSize property so that there are no questions why the image does not fit on the form or control.

As for polymorphism, everything is in stock. Your form inherits all the functionality of the parent Form class and changes the behavior of the OnPaint base method.

You have the workpiece, the rest is already your work, and the most important part is to figure out how it works, and MSDN can seriously help with this, for example, working code examples and even step-by-step instructions for common tasks. Get used to reading the documentation - this is an extremely useful lesson.