I have a MainForm which has a panel. I have added a UserControl1 in it while start the application. by clicking a button inside of UserControl1 trying to call UserControl2 to add the panel and clear UserControl1 from main form panel. Then by clicking second button inside of UserControl2 trying to call UserControl1 and clear UserControl2 from main forms panel. But in my code when I call UserControl2 MainForm comes blank. what is the problem? here is code:
namespace UserControlTest
{
public partial class MainForm : Form // main from
{
private static MainForm _instance;
public static MainForm Instance
{
get
{
if (_instance == null)
{
_instance = new MainForm();
}
return _instance;
}
}
public MainForm()
{
InitializeComponent();
if (!panel1.Controls.Contains(UserControl1.Instance)) // checking UserControl1 existance
{
panel1.Controls.Add(UserControl1.Instance); // add
UserControl1.Instance.Dock = DockStyle.Top; // dock it
UserControl1.Instance.BringToFront(); // bring to front of panel1
}
}
public void CallUserControl1() // method helps to bring UserControl1 to front of panel 1
{
if (!panel1.Controls.Contains(UserControl1.Instance))
{
panel1.Controls.Clear();// clearing controls
panel1.Controls.Add(UserControl1.Instance);
UserControl1.Instance.Dock = DockStyle.Top;
UserControl1.Instance.BringToFront();
}
else
{
UserControl1.Instance.BringToFront();
}
}
public void CallUserControl2()// method helps to bring UserControl2 to front of panel 1
{
if (!panel1.Controls.Contains(UserControl2.Instance))
{
panel1.Controls.Clear();// clearing controls
panel1.Controls.Add(UserControl2.Instance);
UserControl2.Instance.Dock = DockStyle.Top;
UserControl2.Instance.BringToFront();
}
else
{
UserControl2.Instance.BringToFront();
}
}
}
}
// first user control which helps to call UserControl2 to come front page
public partial class UserControl1 : UserControl
{
private static UserControl1 _instance;
public static UserControl1 Instance
{
get
{
if (_instance == null)
{
_instance = new UserControl1();
}
return _instance;
}
}
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MainForm mainForm = new MainForm();
mainForm.CallUserControl2();
}
}
// second user control which helps to call UserControl1 to come front page
public partial class UserControl2 : UserControl
{
private static UserControl2 _instance;
public static UserControl2 Instance
{
get
{
if (_instance == null)
{
_instance = new UserControl2();
}
return _instance;
}
}
public UserControl2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MainForm main = new MainForm();
main.CallUserControl1();
}
}
Update: Thanks to comment of #RonBeyer this is worked but needed to clear controls of panel first than
var main = this.FindForm() as MainForm;
main.CallUserControl1();
Related
I have 2 UserControls on my Form1. They are stacked on top each other within a panel. In UserControl1 i load the image from a file using the OpenFileDialog. On my Form1 i have also a Toggle Button, where the user can switch between the two UserControls. This works pretty well, but how can I pass the image from UserControl1 (contains image on panel) to UserControl2 (contains pictureBox control for displaying the image) as soon as the Toggle Button is set to the state - toggle button is checked ? Thanks for any hint !
UserControl1
public partial class UserControl1 : UserControl
{
private static UserControl1 _instance;
public static UserControl1 Instance
{
get
{
if (_instance == null)
_instance = new UserControl1();
return _instance;
}
}
private Image _icon;
public Image Icon
{
get { return _icon; }
set { _icon = value; panel1.BackgroundImage = value; }
}
private void OpenToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
using (OpenFileDialog OFD = new OpenFileDialog())
{
OFD.Filter = "Picture Files|*.bmp;*.jpg;*.gif;*.png;*.tif";
if (OFD.ShowDialog() == DialogResult.OK)
{
panel1.BackgroundImage = Image.FromFile(OFD.FileName);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
UserControl2
public partial class UserControl2 : UserControl
{
public UserControl2()
{
InitializeComponent();
}
private static UserControl2 _instance;
public static UserControl2 Instance
{
get
{
if (_instance == null)
_instance = new UserControl2();
return _instance;
}
}
Form1
private void ToggleButton1_CheckedChanged(object sender, EventArgs e)
{
if (!toggleButton1.Checked)
{
if (!panel1.Controls.Contains(UserControl1.Instance))
{
panel1.Controls.Add(UserControl1.Instance);
UserControl1.Instance.BringToFront();
}
else
{
UserControl1.Instance.BringToFront();
}
}
if (toggleButton1.Checked)
{
if (!panel1.Controls.Contains(UserControl2.Instance))
{
panel1.Controls.Add(UserControl2.Instance);
UserControl2.Instance.BringToFront();
}
else
{
UserControl2.Instance.BringToFront();
}
}
}
I have a problem with displaying UserControl on my Form.
The program in the nutshell:
In Form1 I have a button. After clicking this, in the Panel (container) my first UserControl (new.cs) are dynamically loaded.
On that panel I have another button that leads to another UserControl (choice.cs) and I want to display it in the same Panel (container) on my Form1.
The first point works good, but I have a problem with second one. I think I have to correct choice_button_Click function. Is there an easy way to do it?
Here is my code:
Form1.cs:
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void new_button_Click(object sender, EventArgs e)
{
if (!container.Controls.Contains(#new.Instance))
{
container.Controls.Add(#new.Instance);
#new.Instance.Dock = DockStyle.Fill;
#new.Instance.BringToFront();
}
else
{
#new.Instance.BringToFront();
}
}
public Panel getContainer()
{
return container;
}
}
}
new.cs:
namespace WindowsFormsApp1
{
public partial class #new : UserControl
{
private static #new _instance;
public static #new Instance
{
get
{
if (_instance == null)
_instance = new #new();
return _instance;
}
}
public #new()
{
InitializeComponent();
}
private void choice_button_Click(object sender, EventArgs e)
{
using (Form1 main = new Form1())
{
if (!main.getContainer().Controls.Contains(choice.Instance))
{
main.getContainer().Controls.Add(choice.Instance);
choice.Instance.Dock = DockStyle.Fill;
choice.Instance.BringToFront();
}
else
{
choice.Instance.BringToFront();
}
}
}
}
}
choice.cs:
namespace WindowsFormsApp1
{
public partial class choice : UserControl
{
private static choice _instance;
public static choice Instance
{
get
{
if (_instance == null)
_instance = new choice();
return _instance;
}
}
public choice()
{
InitializeComponent();
}
}
}
Your functional problem is that you aren't placing choice.Instance inside your instance of your Form1. You are creating a new form instead, placing it there, then discarding that form.
However, you also have an issue in your design, where you are violating the principal wherein a UserControl shouldn't be directly accessing and modifying its parent form. You would be better off adding an event to #new, raising that event from the button click, then handling that event in your form instance.
For example:
new.cs:
namespace WindowsFormsApp1
{
public partial class #new : UserControl
{
private static #new _instance;
public static #new Instance
{
get
{
if (_instance == null)
_instance = new #new();
return _instance;
}
}
public event EventHandler StepCompleted;
public #new()
{
InitializeComponent();
}
private void choice_button_Click(object sender, EventArgs e)
{
StepCompleted?.Invoke(this, EventArgs.Empty);
}
}
}
And Form1.cs:
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void new_button_Click(object sender, EventArgs e)
{
if (!container.Controls.Contains(#new.Instance))
{
container.Controls.Add(#new.Instance);
#new.Instance.Dock = DockStyle.Fill;
#new.Instance.BringToFront();
}
else
{
#new.Instance.BringToFront();
}
}
private void new_StepCompleted(object sender, EventArgs e)
{
if (!container.Controls.Contains(choice.Instance))
{
container.Controls.Add(choice.Instance);
choice.Instance.Dock = DockStyle.Fill;
choice.Instance.BringToFront();
}
else
{
choice.Instance.BringToFront();
}
}
}
}
Now you're obviously going to be working on the same form instance, since it itself is the one handling the event. Also, #new doesn't need to do any awkward lookup to find the proper Form1 instance and modify the form.
I wanted to load a user control to a panel with a button, but when I tried this code it shows nothing. I wonder if there is a solution for my problem because I've already tried many solutions from internet but nothing worked.
this is my code :
on user cotrol
public partial class UserControl1 : UserControl
{
public static UserControl1 _instance;
public static UserControl1 Instance {
get {
if (_instance == null)
_instance = new UserControl1();
return _instance;
}
}
public UserControl1()
{
InitializeComponent();
}
}
on winform by button click
private void b1_Click(object sender, EventArgs e)
{
if (!panel5.Controls.Contains(UserControl1.Instance))
{
panel5.Controls.Add(UserControl1.Instance);
UserControl1.Instance.Dock = DockStyle.Fill;
UserControl1.Instance.BringToFront();
}
else
UserControl1.Instance.BringToFront();
}
main form
user control
Thanks for your concern.
try this.
Hope this will help .you
private void set2ControlTopanel(control f) {
try {
p2Form = f;
p2Form.Dock = DockStyle.Fill;
p2Form.Show();
panelTop.Controls.Add(p2Form);
p2Form.BringToFront();
}
catch (Exception ex) {
MsgBox(ex.Message);
}
}
I am new to c# and using windows forms.
I have Form1 with a button (Button_Save) and textbox . and I have user control1 with one button (button1).
What I am trying to do in this program is: when I click on button1, its text appear in textbox (in Form1), then I enter new text and click save, the button1 text change accordingly.
I will explain when the freeze happens:
There are 2 parts:
first part: when I created instance of user control1 in Form1 then I participated in UserControl1Event and run program it works fine and button1 text appears in textbox when I click on it. Second part when I create instance of Form1 in user control1 and participated in Form1Event and run the program the program freezes for long time then gives error pointing at Form1 instance in user control1 (as shown in screen shot).
Anyone knows why this is happening ? what I am doing wrong?
Form1:
public partial class Form1 : Form
{
public event EventHandler Form1Event;
UserControl1 uc1 = new UserControl1();
public Form1()
{
InitializeComponent();
Controls.Add(uc1);
uc1.Visible = true;
uc1.UserControl1Event += new EventHandler(Handleuc1);
}
string Return_TextBox_Txt;
public string TextBox_Txt
{
get { return Return_TextBox_Txt; }
}
public void Handleuc1(object sender, EventArgs e) ////////////Handle uc1 event
{
textBox1.Text = uc1.ButtonText;
}
private void button_save__Click(object sender, EventArgs e)//change button text
{
Return_TextBox_Txt = textBox1.Text;
Form1Event(this, e);
}
}
User Control1:
public partial class UserControl1 : UserControl
{
string BtnTxt;
Form1 frm1 = new Form1();
public event EventHandler UserControl1Event;
public string ButtonText
{
get { return BtnTxt; }
}
private void UserControl1_Load(object sender, EventArgs e)
{
frm1.Form1Event += new EventHandler(HandleForm1Event);
}
public void HandleForm1Event(object sender, EventArgs e)
{
button1.Text = frm1.TextBox_Txt;
}
private void Button1_Click(object sender, EventArgs e)
{
BtnTxt = button1.Text;
UserControl1Event(this, e);
}
}
The problem is that both of your classes depend on each other.
Form1, when created, creates an instance of UserControl1, which in turn creates and instance of Form1, and so on. All this chained creation eventually makes your code throw a StackOverflowException.
It's expected behavior because of you are creating new Form1 instance and on object constructing it creates new UserControl1 instance that also creates new Form1 instance and so on.
If you need to have an owner of UserControl1 inside its instance you can pass it to the UserControl1 constructor:
public partial class Form1 : Form
{
...
UserControl1 uc1;
public Form1()
{
InitializeComponent();
// creates new control and pass owner via constructor parameter
uc1 = new UserControl1(this);
Controls.Add(uc1);
uc1.Visible = true;
uc1.UserControl1Event += new EventHandler(Handleuc1);
}
...
}
public partial class UserControl1 : UserControl
{
Form1 frm1;
public UserControl1(Form1 owner)
{
// save user control owner passed from constructor parameter to local variable
frm1 = owner;
}
...
}
I made a web browser in C# Windows forms, and I made form 3 to be the history, form 3 contains listbox and a button called go!
I want button_click to navigate the webbrowser1 (located in form1) to listbox1.selecteditem.tostring().
In form1 constructor:
public Form1()
{
x = new Form3();
x.Show();
x.Visible = false;
InitializeComponent();
}
and in the button that open the form 3
{
x.Visible = true;
}
in form 3 button that says go :
{
// namespace.form1.webbrowser1.navigate(listbox1.selecteditem.tostring()); //
this.Visible = false;
}
the error in the comment line , what is the solution to access the webbrowser from form 3 !!
Pass Form1 to Form3 constructor as parameter:
class Form3
{
Form1 _parent;
public Form3(Form1 parent)
{
_parent = parent;
}
public void Method()
{
_parent.webbrowser1.navigate(listbox1.selecteditem.tostring());
this.Visible = false;
}
}
also, make webbrowser1 public or better make a public method in Form1:
class Form1
{
public void Navigate(string uri)
{
webbrowser1.navigate(uri);
}
}
and call it from Form3:
public void Method()
{
_parent.Navigate(listbox1.selecteditem.tostring());
this.Visible = false;
}