So I am trying to show the progress of my application from Form2 to Form1, using a huge Label(located on Form1), but the Text proprety of the Label doesn't change using my code.
There is a download process on executed via Form2 and when it finishes I want a label on Form1 to be updated to notify the user of a completion.
Here is the code:
in Form1:
public string LabelText
{
get
{
return this.label1.Text;
}
set
{
this.label1.Text = value;
this.Refresh();
}
}
in Form2:
private void DLClient(string link, string saveloc)
{
webClient = new WebClient();
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
webClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(webClient_DownloadDataCompleted);
webClient.DownloadDataAsync(new Uri(link));
}
private void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString());
}
private void webClient_DownloadDataCompleted(Object sender, DownloadDataCompletedEventArgs e)
{
byte[] downloadedBytes = e.Result;
Stream file = File.Open(saveloc, FileMode.Create);
file.Write(downloadedBytes, 0, downloadedBytes.Length);
file.Close();
webClient.Dispose();
(new Form1()).LabelText = "Desired Text";//the changing code
Close();
I don't think there is a use for the calling code of Form2 within Form1 to be posted because it's pretty much working 100%.
Pass Form2 THE instance of Form1, like in form2's class constructor.
Don't instantiate a new (invisible) Form1, like you're doing here:
(new Form1()).LabelText
The solution:
private Form form1;
public Form2(Form theForm1) {
form1 = theForm1;
}
...
((Form1)form1).LabelText = "It works";
The calling code:
Form2 frm2 = new Form2(this);
"this" is the Form1 instance.
While setting the label text, you are initializing new instance of Form1, so the desired text is actually being set in new Form1 and not in the Form that is already open. These are two different instances and do not know each other.
Ideally I would do this by creating an event for this say, DownloadCompleted or something like this; raise the event in Form2 and handle this event in Form1.
Another quick option would be to have an instance of Form1 in Form2, then you can assign this property just before showing up the Form2. Something like this -
var objForm2 = new Form2();
objForm2.objForm1 = this;
objForm2.ShowDialog();
...and then in Form2 -
objForm1 .LabelText = "Desired Text";//the changing code
Related
I have 2 forms (Form1 and Form2). Form1 has a splitter with two panels. I have added Form2 in the panel2 of the splitter control. I want to pop in and pop out Form2 without creating a new instance of Form2. Please find the code snippet below:
public partial class Form1 : Form
{
private Form2 form2 = null;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
form2 = new Form2();
form2.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
form2.Dock = DockStyle.Fill;
form2.TopLevel = false;
splitContainer1.Panel2.Controls.Add(form2);
form2.Pop += new EventHandler(PopForm);
form2.Show();
}
//button click event handler from Form2
private void PopForm(object sender, EventArgs e)
{
Button b = sender as Button;
if(b.Text.ToUpper() == "POPOUT")
{
splitContainer1.Panel2Collapsed = true;
splitContainer1.Panel2.Controls.Remove(form2);
//need to show the form without creating a new instance to maintain state
form2 = new Form2();
form2.SelectedMailId = 1;
form2.Pop += new EventHandler(PopForm);
form2.SetButtonText = "PopIn";
form2.Show();
}
else
{
//this works fine
splitContainer1.Panel2Collapsed = false;
form2.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
form2.Dock = DockStyle.Fill;
form2.TopLevel = false;
splitContainer1.Panel2.Controls.Add(form2);
}
}
}
How can I show the Form2 without creating a new instance when popping out?
While popout setup the form border styled and toplevel
if(b.Text.ToUpper() == "POPOUT")
{
splitContainer1.Panel2Collapsed = true;
splitContainer1.Panel2.Controls.Remove(form2);
//need to show the form without creating a new instance to maintain state
form2.TopLevel = true;
form2.FormBorderStyle = FormBorderStyle.Sizable;
// setup your settings
form2.Show();
}
I have a Windows Form (let's call it Form1) that opens a second windows form (Form2) to make the user select something from a comboBox.
// create form1
var Form1 = new Form1();
Form1.Show();
// event to open form2
private void openForm2(object sender, EventArgs e)
{
Form2 Form2= new Form2();
Form2.Show();
}
After selecting an item in the comboBox, the user clicks on the "Update" button to update a textBox in Form1 with the selected value.
private void updateForm1(object sender, EventArgs e)
{
// Form1.textBox1 is not accessible
}
I know how to pass a value from Form1 to Form2, but how can I pass a value from Form2 back to the active Form1 ? I can't access the active Form1 without recreating the form.
I found the answer by passing an event handler.
// propertie in form1 to hold the form2 instance to get the value back
private Form2 _form2;
public Form2 form2
{
get { return _form2; }
set { this._form2= value; }
}
// opens the form1
var Form1 = new Form1();
Form1.Show();
// event to open form2
private void openForm2(object sender, EventArgs e)
{
Form2 Form2= new Form2();
Form2.FormClosing += new FormClosingEventHandler(getValueFromForm2);
Form2.Show();
this.form2 = Form2;
}
// event to retrieve the value and update textbox of form1
private void getValueFromForm2(object sender, FormClosingEventArgs e)
{
Control ctrl = this.form2.Controls.Find("theControlWithTheValue", true)[0];
// control is a listbox
ListBox lbox = ctrl as ListBox;
// update form1 textbox
textBoxInForm1.Text = lbox.SelectedItem.ToString();
}
I have two forms Form1 and Form2.
Form1 has a WebBrowser and Form2 contains tab code.
In Form1 on load I have kept the following code to get first tab:
public void Form1_Load(object sender, EventArgs e)
{
TabPage t = new TabPage();
Form2 newtab = new Form2();
newtab.Show();
newtab.TopLevel = false;
newtab.Dock = DockStyle.Fill;
t.Controls.Add(newtab);
tabControl1.TabPages.Add(t);
}
This is working fine.
Now in Form2 I have a menu item which when clicked will open new tab. Its code is as follows:
public void addTabToolStripMenuItem_Click(object sender, EventArgs e)
{
TabPage t = new TabPage();
Form2 newtab = new Form2();
newtab.Show();
newtab.TopLevel = false;
newtab.Dock = DockStyle.Fill;
t.Controls.Add(newtab);
Form1 b = new Form1();
b.tabControl1.TabPages.Add(t);
}
But I don't get a new tab. i.e. When I click the menu item nothing happens.
You are creating a new Form1 in your click Handler, it is not the Form1 that you used to create the instance of Form2 in. Your best bet would be to use the Show method that allows you to set the owning form and as long as your TabControl's Modifier is public it will work. This is IMHO really not the way to go. I would look into creating an event and subscribe to that.
public void Form1_Load(object sender, EventArgs e)
{
TabPage t = new TabPage();
Form2 newtab = new Form2();
newtab.Show(this); //note the change here
newtab.TopLevel = false;
newtab.Dock = DockStyle.Fill;
t.Controls.Add(newtab);
tabControl1.TabPages.Add(t);
}
This will enable you to do this:
((Form1)this.Owner).tabControl1.TabPages.Add(t);
I'm creating LinkLabel in Form2 and Form3 with the same code. Form2 and Form3 are separate classes so the names don't interferer. They are both created, but in the Form 3 links open, in the Form2 nothing happens.
This is the code for Form2
public partial class Form2 : Form
{
public void createFormEntry(List<string> videoId)
{
LinkLabel link = new LinkLabel();
link.Name = "link";
link.AutoSize = true;
link.Location = new Point(76, 8);
link.Text = "www.example.com";
link.LinkClicked += new LinkLabelLinkClickedEventHandler(link_LinkClicked);
this.Controls.Add(link);
}
private void link_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("http://www.example.com");
}
}
And this is for the Form3
public partial class Form3 : Form
{
private void createFormEntry(Feed<Video> videoFeed)
{
LinkLabel link = new LinkLabel();
link.Name = "link";
link.AutoSize = true;
link.Location = new Point(76, 8);
link.Text = "www.example.com";
link.LinkClicked += new LinkLabelLinkClickedEventHandler(link_LinkClicked);
this.Controls.Add(link);
}
private void link_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("http://www.example.com");
}
}
They are in different classes. Form2 opens before Form3.
What could be wrong?
EDIT: now when I added more code, I see in Form2 createFormEntry is public and in Form3 it is set as private.
Could that be a reason?
Your trying to open a link without telling the program how or what to open that link in. You should tell it to search it in a program or something!
How can i control all my forms from main ()
Form1 frm1 = new Form1();
Form1 frm2 = new Form1();
Form1 frm3 = new Form1();
Application.Run(frm1); // This way form-control goes to the frm1.
// In frm1 i have to write
frm1.Clicked += ()=>frm2.Show;
// I want the form-controlling style more explicitly
// I dont want to use Application.Run()
frm1.Show();
frm1.Clicked += frm2.Show();
form.ShowDialog () helps much but the execution stack can overflow.
Form.Show and Form.Hide methods runs when an application class has been set.
In Application.Run (Form) way there's always a main form. and i dont want this one. Any other approach you use in this problem
Your problem is, that you have four forms. All of them should exist side by side, but because you made Form1 to the master you got some problems.
To solve this you need another FormMaster above all four of them. This one will be started from Application.Run(). Now this form can be Visible = false, but in its constructor you can create all your four forms and decide how they will be glued together, which one will be shown first and under which circumstances your whole application will be closed.
The usual way is to use event handlers.
All I can understand is that you have several WinForms and you want some main Form to control them? Well, if I understanding/assumption is correct, then about controlling like following?
public partial class Form3 : Form
{
private void Form3_Load(object sender, EventArgs e)
{
Demo();
}
MyMainForm main = new MyMainForm(); //Your actual form
private void Demo()
{
main.Click += new EventHandler(main_Click);
main.ShowDialog();
}
void main_Click(object sender, EventArgs e)
{
MyNotificationForm notify = new MyNotificationForm();//Your notification form
notify.Name = "notify";
notify.Click += new EventHandler(notify_Click);
notify.ShowDialog(main);
}
void notify_Click(object sender, EventArgs e)
{
MyWarningForm warning = new MyWarningForm();//Your warning form
warning.Click += new EventHandler(warning_Click);
warning.ShowDialog(main.ActiveMdiChild);
}
void warning_Click(object sender, EventArgs e)
{
((Form)sender).Close(); //Click on form would close this.
}
}
Following is how I'd implement the classes.
public class CBaseForm : Form
{ public CBaseForm() { this.Text = "Main App"; } }
public class MyWarningForm : CBaseForm
{ public MyWarningForm() { Label lbl = new Label(); lbl.Text = "Warning Form"; this.Controls.Add(lbl); } }
public class MyNotificationForm : CBaseForm
{ public MyNotificationForm() { Label lbl = new Label(); lbl.Text = "Notification Form"; this.Controls.Add(lbl); } }
public class MyMainForm : CBaseForm
{ public MyMainForm() { Label lbl = new Label(); lbl.Text = "Controller Form"; this.Controls.Add(lbl); } }
And you MainForm would start conventionally
Application.Run(new Form3());
Let me know if I dragged your question to 180 degrees!