-1

I have 3 classes in my program:

  • Arrow (it contains the logic for drawing arrow, and all required information about it, like: starting point, ending point, etc.)

  • Form1 (that contains the drawing area(basically panel), where this arrow will be located in the future)

  • UserControl, is located in Form1 (I did Form1.Controls.Add(UserControl)). It has a Form1 as a parent. In this UserControl, I have a button, when I click it, an arrow should be drawn on the Form1's drawing area.

    And I'm so confused with the logic that this program should have. I tried to create Arrow class object in the UserControl.Button_Click(), and call all the Arrow's methods from there, but I can't access to Form1's controls. I also thought maybe I can create object of Arrow in the Form1. So I tried to subscribe event UserControl.Button_Click() with some Form1's delegate, but I don't know how to do it. In this case, does delegate and the method that this delegate have as a reference should be Static?

So this is how my code looks like. (I little bit simplified and shortened my classes) Arrow:

public class Arrow
{
    public Point PointBeginning { get => pointBeginning; set => pointBeginning = value; }
    public Point PointEnding { get => pointEnding; set => pointEnding = value; }
    public int ArrowClickCounter { get => arrowClickCounter; set => arrowClickCounter = value; }

    public void Draw(object sender, MouseEventArgs e)
    {
        //code for drawing
    }
}

Form1:

public class Form1
{
    public delegate void DrawArrowDelegate(object sender, MouseEventArgs e);
    DrawArrowDelegate drawArrowDelegate = DrawArrow;
    /* .. */

    private void DrawArrow(object sender, MouseEventArgs e)
    {
        Arrow arrow = new Arrow();
        arrow.PointBegining = //some point
        arrow.PointEnding = //some another point
        arrow.Draw(sender, e);
    }
}

UserControl:

public class UserControl
{
    /*...*/
    
    private void button_MouseClick(object sender, MouseEventArgs e)
    {
        //And here i somehow want to call delegate. But don't know how :(
    }
}

Sorry for such confused code :(

Can you please recommend me something?

Community
  • 1
  • 1
Don chan
  • 35
  • 7

3 Answers3

2
  1. Your Arrow class could potentially have a DrawMethod which takes a control
  2. Your UserControl, should publish events
  3. You form should listen to the UserControl Events
  4. Your form should override OnPaint to draw the method on demand
TheGeneral
  • 79,002
  • 9
  • 103
  • 141
  • I guess i have a problems with 3. How can i listen it from form? Can you please give me some links where i can read about that? Thank you – Don chan Feb 17 '20 at 01:38
  • 1
    @Svemir https://stackoverflow.com/questions/7880850/how-do-i-make-an-event-in-the-usercontrol-and-have-it-handled-in-the-main-form – TheGeneral Feb 17 '20 at 01:39
  • sorry again, i'm going through this code from this link, but i have one question. In the form we writing UserControl1.ButtonClick += new EventHandler(UserControl_ButtonClick); But here UserControl1 is an object of UserControl, right? But in my program i have a lot of userControls that creating dynamically in the code. So how can i use UserControl1.ButtonClick without setting it to specific object of UserControl class but for all objects? Sorry for such silly quiestion. – Don chan Feb 17 '20 at 02:49
  • 1
    @Svemir You will need to set them in code. Maybe best to ask another question, reference to question i sent, show your code where you are creating these in your own code. This will be easily answered. however its hard to do in comments – TheGeneral Feb 17 '20 at 02:52
  • 1
    @Svemir , you can do `UserControl.Click += Usercontrol_click;` (**If your** `UserControl` **contains a click event, that is**) – Momoro Feb 17 '20 at 03:14
  • @MichaelRandall thank you for your help! Finally i remember where i putting in my code UserControls to the Form, so now i just do userControl.ButtonClick += new EventHandler(UserControl_ButtonClick); It works perfect! Thank you so much again! – Don chan Feb 17 '20 at 04:42
1

Arrow class:

    public class Arrow
    {
        public Point PointBeginning { get; set; }
        public Point PointEnding { get; set; }
        public int ArrowClickCounter { get; set; }

        public void Draw()
        {
            //code for drawing
        }
    }

UserControl.cs:

    public delegate void CreateArrowEventArgs(Arrow arrow);
    public event CreateArrowEventArgs OnCreateArrow; 
    private void button1_Click(object sender, EventArgs e)
    {
        if(this.OnCreateArrow!=null)
        {
            // Create Arrow object which you will have access to in your Form
            Arrow arrowToDraw = new Arrow();

            // Fire The Event
            this.OnCreateArrow.Invoke(arrowToDraw);
        }
    }

Form codebehind :

    private void Form1_Load(object sender, EventArgs e)
    {
        // Create User Control
        var UserCtrl = new UserControl1();

        // Register Event
        UserCtrl.OnCreateArrow += UserCtrl_OnCreateArrow;

        //Add Control to Form
        this.Controls.Add(UserCtrl);
    }

    // You get the Arrow object for use here
    private void UserCtrl_OnCreateArrow(Arrow arrow)
    {
        arrow.Draw();
    }
SerhatDev
  • 241
  • 1
  • 4
0

It sounds like you're having trouble accessing Form1's Controls, so try this:

Form1 f1 = new Form1();

foreach(Button b in f1.Controls)
{
  //Your code..
}

There's also:

this.Controls

And, with calling the events of another control,

button1_Click(sender, e);

As for adding an event to the click of, say, a button,

button1.Click += button1_Click;

Those should work to access the controls.

I can provide more information if needed :)

Momoro
  • 599
  • 4
  • 23
  • 1
    This access controls in a new Form1 you just created and never displayed, not the existing form. – Dour High Arch Feb 17 '20 at 01:35
  • Sorry, i explained my problem not properly, i guess, sorry for that :( I mean, i have a form and have a UserControl with button, and when i click on the button i want to call some methods on the form. But thank you, anyway for your answer! – Don chan Feb 17 '20 at 01:44
  • 1
    You could use, for example, `Button1_Click(sender, e);` – Momoro Feb 17 '20 at 03:09
  • 1
    @DourHighArch , I know - **If you want to access the current _existing_ form, do** `this.Controls` – Momoro Feb 17 '20 at 03:11
  • 1
    @Svemir **no problem! :)** – Momoro Feb 17 '20 at 04:43