How notify that form that executed a thread in other class? - c#

I have two forms called frm1 and frm2:
public partial class frm1 : Form
{
private WebMethods wm;
public frm1()
{
InitializeComponent();
}
private void button_Click(object sender, EventArgs e)
{
wm = new WebMethods();
wm.test();
}
}
public partial class frm2 : Form
{
private WebMethods wm;
public frm2()
{
InitializeComponent();
}
private void button_Click(object sender, EventArgs e)
{
wm = new WebMethods();
wm.test();
}
}
now I have a class called WebMethods :
class WebMethods
{
private BackgroundWorker backgroundWorker;
public void stop(){
backgroundWorker.CancelAsync();
}
public void test()
{
if (backgroundWorker.IsBusy != true)
{
this.backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerSupportsCancellation = true;
backgroundWorker.DoWork += new DoWorkEventHandler(_PostRequest);
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_PostRequestComplet ed);
backgroundWorker.RunWorkerAsync();
}
}
private void _PostRequest(object sender, DoWorkEventArgs e)
{
// ...
}
private void _PostRequestCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// ...
}
}
now I want when backgroundworker thread finished and _PostRequestCompleted event executed, it notify that form that executed test() method.
for example if frm1 executed test() method at end _PostRequestCompleted() method notify frm1 that thread was finished. for example _PostRequestCompleted executes a method in frm1 after finishing thread.
but I dont know how do this ??

Declare an event in WebMethods class and register it in your form classes.
class WebMethods
{
public event EventHandler PostRequestCompletedEvent;
private void _PostRequestCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// ...
if (PostRequestCompletedEvent != null)
{
PostRequestCompletedEvent(this, new EventArgs());
}
}
}
Now register this event in your form classes.
public partial class frm1 : Form
{
private WebMethods wm;
public frm1()
{
InitializeComponent();
}
private void button_Click(object sender, EventArgs e)
{
wm = new WebMethods();
wm.PostRequestCompletedEvent += wm_PostRequestCompletedEvent;
wm.test();
}
void wm_PostRequestCompletedEvent(object sender, EventArgs e)
{
// notify frm1 that thread was finished
}
}
public partial class frm2 : Form
{
private WebMethods wm;
public frm2()
{
InitializeComponent();
}
private void button_Click(object sender, EventArgs e)
{
wm = new WebMethods();
wm.PostRequestCompletedEvent += wm_PostRequestCompletedEvent;
wm.test();
}
void wm_PostRequestCompletedEvent(object sender, EventArgs e)
{
// notify frm2 that thread was finished
}
}

Related

Timer from another form not stopping

Architecture
___ParentForm
|___Timer
|___Panel___ChildForm
|___StopButton
I've got a ParentForm with an attached Timer and a Panel containing the ChildForm.
Problem encountered
I want to stop the ParentForm's timer from the ChildForm but the timer is never stopping.
What I've tried
// timer modifiers = Public
private void stopButton_Click(object sender, EventArgs e)
{
ParentForm parentForm = new ParentForm();
parentForm.timer.Stop();
parentForm.timer.Enabled = false;
}
Create an event in the child form and subscribe to the event in the parent form. Clicking the button in the child form raises the event. In the event handler on the parent form, stop the timer.
ParentForm.cs
public partial class ParentForm : Form
{
ChildForm childForm = null;
public ParentForm()
{
InitializeComponent();
}
private void ParentForm_Load(object sender, EventArgs e)
{
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
toolStripStatusLabel2.Text = DateTime.Now.ToString("HH:mm:ss");
statusStrip1.Refresh();
}
private void btnOpenChildForm_Click(object sender, EventArgs e)
{
if (childForm == null || childForm.IsDisposed)
{
childForm = new ChildForm();
//subscribe to events
childForm.FormClosed += ChildForm_FormClosed;
childForm.StopTimerButtonClicked += ChildForm_StopTimerButtonClicked;
childForm.Show();
}
else
{
childForm.WindowState = FormWindowState.Normal;
childForm.Activate();
}
}
private void ChildForm_FormClosed(object sender, FormClosedEventArgs e)
{
//unsubscribe from events
childForm.FormClosed -= ChildForm_FormClosed;
childForm.StopTimerButtonClicked -= ChildForm_StopTimerButtonClicked;
childForm = null;
}
private void ChildForm_StopTimerButtonClicked(object sender, bool e)
{
//stop timer
timer1.Stop();
}
}
ChildForm.cs
public partial class ChildForm : Form
{
public delegate void EventHandlerStopTimerButtonClicked(object sender, bool e);
//event that subscribers can subscribe to
public event EventHandlerStopTimerButtonClicked StopTimerButtonClicked;
public ChildForm()
{
InitializeComponent();
}
private void btnStop_Click(object sender, EventArgs e)
{
if (StopTimerButtonClicked != null)
{
//raise event
StopTimerButtonClicked(this, true);
}
}
}

Three buttons in window form opening a same another form

I have three buttons in a window form to open 3 differnet forms, but these are opening same form which should be opened by button1 only.
public partial class Home : Form
{
public Home()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Task addnew = new Task();
addnew.Show();
}
private void button2_Click(object sender, EventArgs h)
{
Task History = new Task();
History.Show();
}
private void button3_Click(object sender, EventArgs v)
{
Task Evaluate = new Task();
Evaluate.Show();
}
}
if your form name are Task , History and Evaluate then Initialize your three from in three method
public partial class Home : Form
{
public Home()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Task addnew = new Task();
addnew.Show();
}
private void button2_Click(object sender, EventArgs h)
{
History history = new History();
history.Show();
}
private void button3_Click(object sender, EventArgs v)
{
Evaluate evaluate = new Evaluate();
evaluate.Show();
}
}

get value from startup window

I changed the startup window at the app.xaml with this code:
Startup="ApplicationStart"
At the app.xaml.cs file is this method:
private void ApplicationStart(object sender, StartupEventArgs e)
{
Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
ChooseAccountWindow chooseAccountWindow = new ChooseAccountWindow();
chooseAccountWindow.ShowDialog();
}
The Code of the window (ChooseAccountWindow()):
public partial class ChooseAccountWindow : MetroWindow
{
public ChooseAccountWindow()
{
InitializeComponent();
}
private void btnDastaschentuch2013_Click(object sender, RoutedEventArgs e)
{
//send value "dastaschentuch2013" to the main window
}
private void btnSkeptar_de_Click(object sender, RoutedEventArgs e)
{
//send value "skeptar_de" to the main window
}
private void btnAsdf_de_Click(object sender, RoutedEventArgs e)
{
//send value "asdf_de" to the main window
}
}
If I press one of the button`s, then a value should be send to the main code. How can I do that?
Answer
I had to change the MainWindow.xaml.cs code:
namespace EbayManager
{
public partial class MainWindow : MetroWindow
{
private string selectedAccount;
public MainWindow()
{
InitializeComponent();
}
public MainWindow(string selectedAccount): this()
{
this.selectedAccount = selectedAccount;
}
}
}
public partial class ChooseAccountWindow : MetroWindow
{
public string Result { get; set; }
public ChooseAccountWindow()
{
InitializeComponent();
}
private void btnDastaschentuch2013_Click(object sender, RoutedEventArgs e)
{
this.Result = "dastaschentuch2013";
this.Close();
}
private void btnSkeptar_de_Click(object sender, RoutedEventArgs e)
{
this.Result = "skeptar_de";
this.Close();
}
private void btnTrachsel_de_Click(object sender, RoutedEventArgs e)
{
this.Result = "trachsel_de";
this.Close();
}
}
In App.xaml remove StartupUri to prevent automatical main window opening
In App.xaml.cs:
private void ApplicationStart(object sender, StartupEventArgs e)
{
Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
ChooseAccountWindow chooseAccountWindow = new ChooseAccountWindow();
chooseAccountWindow.ShowDialog();
MainWindow main = new MainWindow(chooseAccountWindow.Result);
// insert your startup uri class name instead of MainWindow;
// add constructor to this window that will take string as input parameter
main.Show();
}
If I read you correctly, you can reference the main window like this:
Application.Current.MainWindow and then set a property on it.
void Button_Click(object sender, RoutedEventArgs e)
{
Application.Current.MainWindow.MyProperty = "SomeValue";
MainWindow.ShowDialog();
this.Close();
}

How to send all events of a child control to its parent control (custom control)?

I have one custom control containing three child controls (Panel with PictureBox control and Label) and I want to send all events of a child controls to its parent control (custom control).
I know there are lots of answers regarding this problem, but I cannot figure out it with a simple solution.
Here is my example
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
UserControl1 uc1 = new UserControl1();
this.Controls.Add(uc1);
}
}
public partial class UserControl1 : UserControl
{
public PictureBox ChildPictureBox { get; set; }
public UserControl1()
{
PictureBox pictureBox1 = new PictureBox();
pictureBox1.Size = new Size(150, 150);
pictureBox1.BackColor = Color.Red;
pictureBox1.Click += PictureBox1_Click;
this.Controls.Add(pictureBox1);
ChildPictureBox = pictureBox1;
this.Click += UserControl1_Click;
}
private void UserControl1_Click(object sender, EventArgs e)
{
MessageBox.Show("User control click");
}
private void PictureBox1_Click(object sender, EventArgs e)
{
MessageBox.Show("pic clicked");
}
}
The following code is the example, here UserControl1 has PictureBox and Panel and their click events are hooked into MainForm i-e MyForm as named. You can modify it as per your requirements.
UserControl1.cs
public partial class UserControl1 : UserControl
{
public delegate void PictureBoxClickHandler(object sender, EventArgs e);
public event PictureBoxClickHandler PictureBoxClick;
public delegate void PanelClickHandler(object sender, EventArgs e);
public event PanelClickHandler PanelClick;
public delegate void PictureBoxDoubleClickHandler(object sender, EventArgs e);
public event PictureBoxDoubleClickHandler PictureBoxDoubleClick;
public delegate void PictureBoxMouseMoveHandler(object sender, MouseEventArgs e);
public event PictureBoxMouseMoveHandler PictureBoxMouseMove;
public UserControl1()
{
InitializeComponent();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
if (PictureBoxClick != null)
{
PictureBoxClick(sender, e);
}
}
private void panel1_Click(object sender, EventArgs e)
{
if (PanelClick != null)
{
PanelClick(sender, e);
}
}
private void pictureBox1_DoubleClick(object sender, EventArgs e)
{
if (PictureBoxDoubleClick != null)
{
PictureBoxDoubleClick(sender, e);
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (PictureBoxMouseMove != null)
{
PictureBoxMouseMove(sender, e);
}
}
}
MyForm.cs
public class MyForm : Form
{
public MyForm()
{
InitializeComponent();
var userControl1 = new UserControl1();
Controls.Add(userControl1);
userControl1.PictureBoxClick += userControl1_PictureBoxClick;
userControl1.PanelClick += userControl1_PanelClick;
userControl1.PictureBoxDoubleClick+=userControl1_PictureBoxDoubleClick;
userControl1.PictureBoxMouseMove+=userControl1_PictureBoxMouseMove;
}
private void userControl1_PanelClick(object sender, EventArgs e)
{
//Click: Panel on userControl1
}
private void userControl1_PictureBoxClick(object sender, EventArgs e)
{
//Click: PictureBox on userControl1
}
private void userControl1_PictureBoxMouseMove(object sender, MouseEventArgs e)
{
throw new NotImplementedException();
}
private void userControl1_PictureBoxDoubleClick(object sender, EventArgs e)
{
throw new NotImplementedException();
}
}
EDIT:
public partial class UserControl1 : UserControl
{
public PictureBox ChildPictureBox { get; set; }
public UserControl1()
{
InitializeComponent();
ChildPictureBox = pictureBox1;
}
//----
}
Now in form
public class MyForm : Form
{
public MyForm()
{
InitializeComponent();
PictureBox pictureBox = userControl1.ChildPictureBox;
//now work with pictureBox here
pictureBox.Click += pictureBox_Click;
}
private void pictureBox_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
}
I think you can do this, but you should know that uncommon events cannot be linked to other controls.
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
foreach (Control control in this.Controls)
{
control.Click += new EventHandler(control_Click);
}
}
private void control_Click(object sender, EventArgs e)
{
this.UserControl1_Click(sender, e);
}
private void UserControl1_Click(object sender, EventArgs e)
{
}
}

WinForms form freezes

On a form (F1) i have a button, from which if i create another form (lets call it F2) and show it there's no problem
but i'd like to do something like this
Some thread in my app is running a connection and listens for messages from a server. when a message arrives, my main form is registered to get an event that runs a function. From that function i'm trying to create and show the F2 type form (empty, nothing modified in it): it shows it but then it freezes my application.
more exactly:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ConnectionManagerThread.getResponseListener().MessageReceived += Form1_OnMessageReceived;
}
private void Form1_OnMessageReceived(object sender, MessageEventArgs e) {
Form2 f2 = new Form2();
f2.Show();
}
}
I think the reason is you are performing cross thread operations. You need to put the creation of the form on the UI thread before creating form2. I think following will help you
public delegate void ShowForm(object sender, MessageEventArgs e);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ConnectionManagerThread.getResponseListener().MessageReceived += Form1_OnMessageReceived;
}
private void Form1_OnMessageReceived(object sender, MessageEventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new ShowForm((Form1_OnMessageReceived), new object[] { sender, e }));
}
else
{
Form2 f2 = new Form2();
f2.Show();
}
}
}
using Ram's code i finally got to this and it works
thanx!
public delegate void ShowForm(object sender, MessageEventArgs e);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ConnectionManagerThread.getResponseListener().MessageReceived += Form1_OnMessageReceived;
}
private void Form1_OnMessageReceived(object sender, MessageEventArgs e)
{
ShowForm2(sender, e);
}
private void ShowForm2(object sender, MessageEventArgs e)
{
if (this.InvokeRequired)
{
ShowForm f = new ShowForm(ShowForm2);
this.Invoke(f, new object[] { sender, e });
}
else
{
Form2 f2 = new Form2();
f2.Show();
}
}
}

Categories