Why is my Event Null? - c#

I am using windows forms C#.
I have main Form and child form. The event is in the child Form and I subscribed to this event in the main Form. The problem is that when I click button1 in child form it does nothing (it should fire the event so textBox1 prints the text) because the event is still null although the main form has already subscribed to the event. Am I doing something wrong? Please help how can I fire the event once button1 is clicked.
Child Form:
public partial class ChildForm : Form
{
public event EventHandler MyEvent;
private void button1_Click(object sender, EventArgs e)
{
if (myEvent != null)
{
MyEvent(this, e);
}
}
Main Form:
public partial class MainForm : Form
{
ChildForm ChildFrm= new ChildForm ();
ChildFrm.MyEvent += new EventHandler(HandleTheEvent);
private void button1_Click(object sender, EventArgs e)
{
ChildForm childfrm = new ChildForm ();
childfrm.ShowDialog()
}
public void HandleTheEvent(object sender, EventArgs e)
{
textBox1.Text = "event is fired";
}

You are adding the event handler to an another instance of ChildForm. Change MainForm's button1_click to look like this:
private void button1_Click(object sender, EventArgs e)
{
ChildFrm.ShowDialog()
}
And your application should work OK.
Here's the working MainForm.cs:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ChildFrm.MyEvent += new EventHandler(HandleTheEvent);
}
ChildForm ChildFrm = new ChildForm();
private void button1_Click(object sender, EventArgs e)
{
ChildFrm.ShowDialog();
}
public void HandleTheEvent(object sender, EventArgs e)
{
textBox1.Text = "event is fired";
}
}

Subscribe to the event right after creating the form :)
private void button1_Click(object sender, EventArgs e)
{
ChildForm childfrm = new ChildForm();
childfrm.MyEvent += new EventHandler(HandleTheEvent);
childfrm.ShowDialog()
}

Related

How to let know the parent form that the child form is closed

My main form opens child form. When the child form closes the parent form needs to perform some tasks. How the parent can know that the child form was closed.
I have a workaround - the hidden button and I invoke PerformeClick method when the child raises the closing event.
Is there any better (more correct) way of doing it?
Add a listener event for your main/parent form when you instantiate child form. Example below:
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.CustomFormClosed += CloseListener;
f2.Show();
}
private void CloseListener(object sender, EventArgs e, string test)
{
Console.WriteLine(test);
}
Edited for Custom Delegates & Events
Form2 code:
public delegate void CustomFormClosedHandler(object semder, FormClosedEventArgs e, string text);
public event CustomFormClosedHandler CustomFormClosed;
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
CustomFormClosed(sender, e, "Hello World!");
}
One way to do this is:
return DialogResult from FormClosing event handler of Form2
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
this.DialogResult = DialogResult.OK;
}
Run modal ShowDialog() on a new thread from Form1 and wait for the DialogResult
private void button2_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
System.Threading.Tasks.Task.Run(() =>
{
if (f2.ShowDialog() == DialogResult.OK)
{
// do here whatever you want to do
MessageBox.Show("Form2 closed");
}
});
}
All you have to do:
1: Add public static method in the parent form:
public static void ChildFromClosed()
{
//Inform here
MessageBox.Show("Child form is closed!");
}
2: Add a (FormClosed) event in the child form that calls that method from the parent form:
private void frmChild_FormClosed(object sender, FormClosedEventArgs e)
{
//calling the static method in Parents form
frmParent.ChildFromClosed();
}

how to pass string or value from usercontrol to main form in C#

I created a usercontrol that contains many buttons and in the main form I have a textbox.
I add the usercontrol to the main form and I want to click any button on the usercontrol and have the textbox in the main form shows the button text.
The question is how to pass the string of the button in usercontrol to the textbox in the main form? This is what I'm trying to do
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public string a ;
private void button1_Click(object sender, EventArgs e)
{
a = button1.Text;
}
private void button2_Click(object sender, EventArgs e)
{
a = button2.Text;
}
private void button3_Click(object sender, EventArgs e)
{
a = button3.Text;
}
and the main form code is :
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox1.Text = usrCtrl.a;
// usrCtrl come from : Usercontrol1 usrCtrl = new Usercontrol1();
}
and it shows nothing in the textbox.
refer to this answer, you need to create a property changed event.
UserControl.cs class;
public partial class UserControl1 : UserControl
{
public event PropertyChangedEventHandler PropertyChanged;
public UserControl1()
{
InitializeComponent();
}
private string stringA;
public string a
{
get { return stringA; }
set
{
if (value != stringA)
{
stringA = value;
if (PropertyChanged!= null)
{
PropertyChanged(this, new PropertyChangedEventArgs(a));
}
}
}
}
private void button1_Click(object sender, EventArgs e)
{
a = button1.Text;
}
private void button2_Click(object sender, EventArgs e)
{
a = button2.Text;
}
private void button3_Click(object sender, EventArgs e)
{
a = button3.Text;
}
private void button4_Click(object sender, EventArgs e)
{
a = button4.Text;
}
}
On Form's Load we need to define the event,
private void Form1_Load(object sender, EventArgs e)
{
cntr.PropertyChanged += Cntr_PropertyChanged; // press tab + tab after += and it will generate the following method automatically.
}
Here is Event;
private void Cntr_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
textBox1.Text = cntr.a.ToString(); //cntr is the instance of UserControl1
}
Hope helps,
Your code to change the textBox1.Text value is in the wrong event handler.
The textBox1_TextChanged event handler only fires when text in that field changes.
What you need to do is put the line:
textBox1.Text = a;
in the click event handlers.

Change background image of form as soon as button on another form is clicked

I am having two forms (A and B). In form B there are many buttons having different background image. On clicking any of the button I want to change the background image of form A to the background image of the button which was clicked instantly as it is always open behind the form.
formA mai = new formA();
private void button1_Click(object sender, EventArgs e)
{
mai.BackgroundImage = button1.BackgroundImage;
}
This is the code I am using although it changes the background image it doesn't change instantly but if I will open and close the form the background image will be changed.
I don't need like that I need it to change instantly.
Add a field in formB to refer to the formA instance which you want to change its BackgroundImage; and initialize it when you call formB
formB's code-behind:
public partial class formB : Form
{
public formA owner;
public formB()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (owner != null)
owner.BackgroundImage = button1.BackgroundImage;
}
private void button2_Click(object sender, EventArgs e)
{
if (owner != null)
owner.BackgroundImage = button2.BackgroundImage;
}
private void button3_Click(object sender, EventArgs e)
{
if (owner != null)
owner.BackgroundImage = button3.BackgroundImage;
}
}
formA's code-behind:
public partial class formA : Form
{
public formA()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
formB b = new formB();
b.owner = this;
b.ShowDialog();
}
}
Add this.Refresh()
formA mai = new formA();
private void button1_Click(object sender, EventArgs e)
{
mai.BackgroundImage = button1.BackgroundImage;
mai.BringToFront();
mai.Refresh();
}
Call mai.Invalidate() after setting the new image.

Raising an event when button clicked and subscribing it to eventhandler in another class?

I have a form.cs which contains a button and a texbtox, and also a class which handles the event raised when the button is clicked.
basically, when the button is clicked, it should raise an event and the eventHandler in Print class should print text to TboxPrint in the form
this is how my code looks like:
//Declare the delegate
public delegate void EventHandler(object sender, EventArgs e);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//event
public event EventHandler Print;
//Event caller, protected to prevent calling from other classes
protected virtual void OnPrint(System.EventArgs e)
{
if (Print != null) Print(this, e);
}
//raising event
public bool print_action(object value)
{
OnPrint(EventArgs.Empty);
return true;
}
public void BtnPrint_Click(object sender, EventArgs e)
{
PrintClass p = new PrintClass();
Form1 s = new Form1();
s.Print += p.printEventHandler;
print_action(true);
}
}
and the class with method handling the event is:
class PrintClass
{
public void printEventHandler(object sender, EventArgs e)
{
string text = "Print Event occured";
}
}
Apparently nothing is raised.. i believe the way i m raising the event or subscribing to the event handler is wrong. and how i pass the text in eventhandler back to form?
any help is appreciated.. thanks
You simply need and extra event subscription to Button.Click event
private void Form1_Load(object sender, EventArgs e)
{
p = new PrintClass();
button1.Click += cls.printEventHandler;
}
To handle all the buttons on the form you can write a simple snippet like
public Form1()
{
InitializeComponent();
foreach (Button btn in Controls.OfType<Button>())
{
btn.Click += cls.printEventHandler;
}
}
To know which button was clicked you can write PrintClass as
class PrintClass
{
public void printEventHandler(object sender, EventArgs e)
{
Button btn = (Button) sender;
//btn.Name <-- Control name;
//btn.Text<-- Control Text;
}
}
One thing that I am not understanding is, why do you need a extra class if you need to output the result on the same form.
My suggest would be, not to create an extra class just for handling all the Button.Click event
This can work the way you want : I am removing the need for extra class
public Form1()
{
InitializeComponent();
foreach (Button btn in Controls.OfType<Button>())
{
btn.Click += HandleAllButtonClicks;
}
}
private void HandleAllButtonClicks(object sender, EventArgs e)
{
Button btn = (Button) sender;
TboxPrint.AppendText(String.Format("Button Clicked : Name = {0}, Text = {1}", btn.Name, btn.Text));
}

Switch among windows forms

I have a bunch of windows forms. Each form has "Back" and "Next" buttons for switching forms. For example, clicking "Back" on Form3 then we go to Form2. Then clicking "Next" button on Form2 then Form3 is shown.
Now my question is that if we click "Next" from the very beginning, it works smoothly. However if I click "Back" on Form3 then Form2 is displayed, then click "Next" on Form3 go to Form3. The code doesn't goto Form3_Load event.
What is wrong in my code?
public partial class Form3 : Form
{
Form2 FormPrev;
Form4 FormNext;
List<DataRow> drlist = new List<DataRow>();
DataTable dt = new DataTable();
public Form3(Form2 _FormPrev)
{
InitializeComponent();
this.FormPrev = _FormPrev;
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnNext_Click(object sender, EventArgs e)
{
ShowNext();
}
private void btnBack_Click(object sender, EventArgs e)
{
ShowPrev();
}
private void ShowNext()
{
if (FormNext == null)
FormNext = new Form4(this);
FormNext.Show();
this.Hide();
}
private void ShowPrev()
{
FormPrev.Show();
this.Hide();
}
private void Form3_Load(object sender, EventArgs e)
{
// blah blah.
}
Thanks.
A form's Load event is only fired when the form is invoked for the first time. If you subsequently hide the form and reshow it then this is not reloading the form so the form's Load event is not fired.
If you want to use an event to handle when the form is re-displayed then you should look at the following more suitable events:
Activated
Shown
VisibleChanged
Form Load event only gets fired before the form is shown for the first time.
You should use a different event, like maybe Form Activated or GotFocus.
That's a normal behaviour. Load is for load form, not for show. In your case you try to show hided form. If you want to use
form.Show()
than use not a
form.Hide()
but
form.Close()
UPD:
Code should be:
public partial class Form3 : Form
{
List<DataRow> drlist = new List<DataRow>();
DataTable dt = new DataTable();
public Form3()
{
InitializeComponent();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnNext_Click(object sender, EventArgs e)
{
ShowNext();
}
private void btnBack_Click(object sender, EventArgs e)
{
ShowPrev();
}
private void ShowNext()
{
Form4 formNext = new Form4();
formNext.Show();
this.Close();
}
private void ShowPrev()
{
Form2 formPrev = new Form2();
formPrev.Show();
this.Close();
}
private void Form3_Load(object sender, EventArgs e)
{
// blah blah.
}
}
But there is a problem with such colutions - you shouldn't close your main form.

Categories

Resources