Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

User Control Constructors.

Posted on 2011-03-04
12
405 Views
Last Modified: 2013-12-17
Experts,

I`m using C# VS2008 3.5. Windows forms.

I was wondering if I can pass a UserControl to the Constructor of another UserControl. Is that even possible?

This is what I want to achieve -  I need to switch betwween / toggle between two User Controls. I have this working by making them properties of each other and handling the visibility of the UserControls.

I wanted to take a different approach.

Here is what I`m trying to do - I want to load User Control A (UA) on the main form. and then toggle between UA and UB when I click on their buttons.

I was hoping there could be a more elegant way to do it, rather than change their visibility.

Event In Main Form
  private void But_Click(object sender, EventArgs e)
        {
            UA Ax;
            UB Bx;
         
            Ax = new UA(Bx);   //This Won`t wort, But I was hoping I can do it a different way.
            Bx = new UB(Ax);

            panel1.Controls.Clear();
            panel1.Controls.Add(Ax);
        }

//UA User Control
   public partial class UA : UserControl
    {
        public UA()
        {
            InitializeComponent();
        }

        public UA(UB Bx)
        {
            InitializeComponent();
            B = Bx;
        }

        public UB B;

        private void UABut_Click(object sender, EventArgs e)
        {
            this.Controls.Clear();
            this.Controls.Add(B);
        }
    }

//UB UserContol
  public partial class UB : UserControl
    {
        public UB()
        {
            InitializeComponent();
        }

        public UB(UA Ax)
        {
            A = Ax;
            InitializeComponent();
        }

        public UA A;

        private void UBBut_Click(object sender, EventArgs e)
        {
            this.Controls.Clear();
            this.Controls.Add(A);
        }
    }
0
Comment
Question by:San24
  • 6
  • 3
  • 2
  • +1
12 Comments
 
LVL 16

Accepted Solution

by:
BurnieP earned 50 total points
ID: 35040763
Hi,

I think you can do it this way :


UA Ax;
UB Bx;
          
Ax = (UA)Page.LoadControl("UA.ascx");
Bx = (UB)Page.LoadControl("UB.ascx");

panel1.Controls.Clear();
panel1.Controls.Add(Ax);

Open in new window

0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 150 total points
ID: 35041607
Not sure what you're after here...

How about an event based approach?
public partial class MainForm : Form
    {

        private void MainForm_Load(object sender, EventArgs e)
        {
            UA Ax = new UA();
            UB Bx = new UB();
            Ax.HideEvent +=new UA.HideDelegate(Bx.HideMe);
            Bx.HideEvent += new UB.HideDelegate(Ax.HideMe);
            panel1.Controls.Add(Ax);
        }

    }

Open in new window

public partial class UA : UserControl
    {

        public delegate void HideDelegate(Control ctl);
        public event HideDelegate HideEvent;

        private void UABut_Click(object sender, EventArgs e)
        {
            if (HideEvent != null)
            {
                HideEvent(this);
            }
        }

        public void HideMe(Control ctl)
        {
            Control parent = ctl.Parent;
            parent.Controls.Remove(ctl);
            parent.Controls.Add(this);
        }

    }

Open in new window

public partial class UB : UserControl
    {

        public delegate void HideDelegate(Control ctl);
        public event HideDelegate HideEvent;

        private void UBBut_Click(object sender, EventArgs e)
        {
            if (HideEvent != null)
            {
                HideEvent(this);
            }
        }

        public void HideMe(Control ctl)
        {
            Control parent = ctl.Parent;
            parent.Controls.Remove(ctl);
            parent.Controls.Add(this);
        }

    }

Open in new window

0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 300 total points
ID: 35045197
This should do what you require, just mo

//UA User Control
   public partial class UA : UserControl
    {
        public UA()
        {
            InitializeComponent();
        }

        public UA()
        {
            InitializeComponent();
        }

        public UB B;

        private void UABut_Click(object sender, EventArgs e)
        {
            this.Controls.Clear();
            this.Controls.Add(B);
        }
    }

..........................................



Ax = new UA();   
Bx = new UB(Ax);
Ax.B = Bx

Open in new window

0
The New “Normal” in Modern Enterprise Operations

DevOps for the modern enterprise offers many benefits — increased agility, productivity, and more, but digital transformation isn’t easy, especially if you’re not addressing the right issues. Register for the webinar to dive into the “new normal” for enterprise modern ops.

 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 300 total points
ID: 35045200
>>This should do what you require, just mo

oops, that should be
This should do what you require, just remove the passing via constructor and assign after the object exists.
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 300 total points
ID: 35045202
Note - the above will work but I don't think it does what you want.  I'm not certain what you are trying to achieve with this technique though - the logic doesn't seem to match with your description.
0
 

Author Comment

by:San24
ID: 35057168
I`m just trying to switch between user controls [back and forth] and then pass parameters between them. I have an approach similar to both of what you suggested. I was just wondering if I could pass the User Control itself in the constructor, so that I can initialize and do some calculations before the parameters are used.

For Now, this is what I`m doing. What`s you opinion? Is there a better / faster way to do this?





//Main Form
   public Form1()
        {
            InitializeComponent();
        }

        private void But_Click(object sender, EventArgs e)
        {
            AB ABobj = new AB();
            ABobj.A.Bx = ABobj.B;
            ABobj.B.Ax = ABobj.A;

            panel1.Controls.Add(ABobj.A);
            panel1.Controls.Add(ABobj.B);

            ABobj.A.Show();
            ABobj.B.Hide();
        }

    }

    public class AB
    {
        public UA A = new UA();
        public UB B = new UB();
    }

  //UA UserCntrl
  public partial class UA : UserControl
    {
        public UA()
        {
            InitializeComponent();
        }

        public UB Bx;

        private void UABut_Click(object sender, EventArgs e)
        {
            Hide();
            Bx.Show();
        }
    }

    //UB UserCntrl
    public partial class UB : UserControl
    {
        public UB()
        {
            InitializeComponent();
        }

        public UA Ax;

        private void UBBut_Click(object sender, EventArgs e)
        {
            Hide();
            Ax.Show();
        }
    }

Open in new window

0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 300 total points
ID: 35057687
Faster - I doubt it.
Better - depends on what you mean by better.  If it works then it can't be too bad.  (I just tend to think this class AB is complicating things too much, the A and B could just belong to the Form1 and things should work just as well).
0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 150 total points
ID: 35057937
I agree that you're over complicating it...

"I was just wondering if I could pass the User Control itself in the constructor"

You have a chicken and egg problem.  One of the controls has to be created before the other, so they both can't receive a reference in their constructor...
0
 

Author Comment

by:San24
ID: 35058056
Andy - Yes it works. I need to have a seprate class. I can`t have it on the main Form. This is just not merely to organize the code. I have different objects/user controls to load - for simplicity think about it as AB, CD.., XY...depending on what the user chooses. Once that is done, the objects within have to have a switch functionality.

Idle Mind - I agree with the Chicken and Egg comparison, the more I look into it.

What would be the most simplest way?

When I use the word better - I mean using proper programming practices, Unfortunately I`m the only one whose working on this project with no one to give me feed back or help. So, sometimes I tend to question the approach I take.
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 300 total points
ID: 35058285
I'd be tempted to not have the A and B inside the B and A objects.  Instead each has the 'owner' object and instructs that to handle the button event.

eg. something like:

class O
{
A a = new A(this);
B b = new B(this);

BtnClick(Object child)
{
child.Hide();
if(child is A)
{
B.Show();
}
....
}


class A
{
O __parent;
A(O parent)
}

A::ButtonClick()
{
  __parent.BtnClick(this);
}

I hope that makes sense
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 300 total points
ID: 35058292
class A
{
O __parent;
A(O parent)  {__parent = parent};  //missed the assignmnt
}
0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 150 total points
ID: 35058366
"I need to have a seprate class ... the objects within have to have a switch functionality."

You could something very similar to what I have back here:
http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_26865332.html#35041607

...except that the extra class would subscribe to HideEvent() {instead of the form itself} and switch the visibility of the two contained objects.  The two contained objects don't need to have any references to each other as the extra class would do that for them.  You could create a constructor for the extra class that receives the two instances of the usercontrols and it wires them up and stores them within.

Without seeing the big picture its hard to make a good recommendation.

One thought is to make an INTERFACE that the UserControls implement.  The Interface could simply have the HideEvent().  With the Interface implemented by ALL the UserControls your extra class can be completely generic and handle any combination of the types of UserControls you have.
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Help with consolidating excel files using VB.net 2 29
Get month and date in a format 4 31
linq, c# 8 22
C# class library debugging - Breakpoint will not hit. 8 16
Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question