Delegate and event - c#

I have 2 forms.
Form1:
public partial class Panel1
{
public void ShowExport(object sender, EventArgs e)
{
.......
}
}
Form2:
public partial class Panel2
{
public delegate void ShowExportReport(object sender, EventArgs e);
public event ShowExportReport ShowExportClicked;
private void buttonExport_Click(object sender, RoutedEventArgs e)
{
if (ShowExportClicked != null)
{
ShowExportClicked(sender, new EventArgs());
}
}
}
When I click button -
button.Click = buttonExport_Click
How can I call Panel1.ShowExport() from Panel2.buttonExport_Click?

In the Panel1 you have to subscribe the event:
pnl2.ShowExportClicked += new ShowExportReport(ShowExport);

You need to assign the handler for the event ShowExportClicked in Panel 1 class to the Panel 2 class object.
public partial class Panel1
{
Panel2 pnl2;
public Panel1()
{
pnl2 = new Panel2();
pnl2.ShowExportClicked += new ShowExportReport(ShowExport);
}
public void ShowExport(object sender, EventArgs e)
{
.......
}
}

pnl2.ShowExportClicked += ShowExport;

Create your event on Form1. and listen to the event in Form2.
Form1:
public event EventHandler ShowExportChanged;
private void ShowExportChanged()
{
var handler = ShowExportChanged;
if(handler == null)
return;
handler(this, EventArgs.Empty);
}
public void ShowExport(object sender, EventArgs e)
{
ShowExportChanged();
}
Form2:
pnl1.ShowExportChanged+= new OnShowExportChanged(ShowExportChanged);

How can I call Panel1.ShowExport() from Panel2.buttonExport_Click?
By passing (only the necessary) information from form1 when instantiating form2.
Form1.cs:
void ShowForm2_Click()
{
var form2 = new Form2();
form2.ShowExportClicked += ShowExport;
form2.Show();
}
Now from Form2 you can simply call ShowExport on button click.

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);
}
}
}

Lock and Unlock textbox on form1, by command in form2

I have two Forms:
Form1
Form2
Whenever I check/uncheck a CheckBox checkBox1 on Form2 I want to update textbox1.Readonly that is on Form1. If both textbox1 and checkbox1 had been on the same Form it would be easy go:
private void checkBox1_CheckedChanged(object sender, EventArgs e) {
textbox1.Readonly = checkBox1.Checked;
}
What shall I do in my case when textbox1 and checkbox1 are on different Forms?
You can put it like this:
public partial class Form1: Form {
...
// textBox1 is private (we can't access in from Form2)
// so we'd rather create a public property
// in order to have an access to textBox1.Readonly
public Boolean IsLocked {
get {
return textBox1.Readonly;
}
set {
textBox1.Readonly = value;
}
}
}
...
public partial class Form2: Form {
...
private void checkBox1_CheckedChanged(object sender, EventArgs e) {
// When checkBox1 checked state changed,
// let's find out all Form1 instances and update their IsLocked state
foreach (Form fm in Application.OpenForms) {
Form1 f = fm as Form1;
if (!Object.RefrenceEquals(f, null))
f.IsLocked = checkBox1.Checked;
}
}
}
You should use events and delegates.
On Form2, We're create a delegate and event
public delegate void OnCheckedEventHandler(bool checkState);
public event OnCheckedEventHandler onCheckboxChecked;
public void checkBox1_Checked(object sender, EventArgs e)
{
if (onCheckboxChecked != null)
onCheckboxChecked(checkBox1.Checked);
}
And on Form1, we're realize this event:
void showForm2()
{
Form2 f2 = new Form2();
f2.onCheckboxChecked += onCheckboxChecked;
f2.Show();
}
public void onCheckboxChecked(bool checkState)
{
textBox1.ReadOnly = checkState;
}
For simplier and more flexible
Form1:
public class Form1 : System.Windows.Forms.Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 tmpFrm = new Form2();
tmpFrm.txtboxToSetReadOnly = this.txtMyTextBox; //send the reference of the textbox you want to update
tmpFrm.ShowDialog(); // tmpFrm.Show();
}
}
FOrm2:
public class Form2 : System.Windows.Forms.Form
{
public Form2()
{
InitializeComponent();
}
TextBox _txtboxToSetReadOnly = null;
public TextBox txtboxToSetReadOnly
{
set{ this._txtboxToSetReadOnly = value; }
get {return this._txtboxToSetReadOnly;}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if( this._txtboxToSetReadOnly != null) this._txtboxToSetReadOnly.ReadOnly = checkbox1.Checked;
/*
or the otherway
if( this._txtboxToSetReadOnly != null) this._txtboxToSetReadOnly.ReadOnly = !checkbox1.Checked;
*/
}
}

How to get string data in main form from second from, when button on second form is clicked in C# .net?

At first I thought that it won't be a problem for me, but now I can't figure it out. So,
when I click Button1 in main form, form2 opens. Form2 is simple numeric keyboard, that user can enter some data. On form2 is also Save. When user clicks it, entered value should pass to main form and from that moment some event must happen in main form, which contains data from form2. Could you please give me some example or any kind of help? Thanks!
// code from main form to create form2
private void button1_Click(object sender, EventArgs e)
{
// Create a new instance of the Form2 class
Form2 settingsForm = new Form2();
// Show the settings form
settingsForm.Show();
string val = settingsForm.ReturnValue1;
MessageBox.Show(val);
}
//button save on form2
private void button13_Click(object sender, EventArgs e)
{
this.ReturnValue1 = "Something";
this.ReturnValue2 = DateTime.Now.ToString(); //example
this.Close();
//after this, some event should happen in main form !
}
There is a lot of solutions to do what you want; but I think one of these will resolve your problem.
1- Simple and easy: use public properties in Form2, initialize them when buttonSave get clicked, and access them in Form1:
Form2:
public partial class Form2 : Form {
public Form2() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e){
YourDate = "something";
Close();
}
public object YourDate { get; private set; }
}
Form1:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e){
var f2 = new Form2();
f2.ShowDialog();
var data = f2.YourDate;
}
}
2- A better way, is using events which is more flexible and professional programming friendly:
Form2:
public partial class Form2 : Form {
public Form2() {
InitializeComponent();
}
// create an event of Action<T> which T is your data-type. e.g. in this example I use an object.
public event Action<object> SaveClicked;
// create an event invocator, to invoke event whenever you want
protected virtual void OnSaveClicked(object data){
var handler = SaveClicked;
if (handler != null)
handler(data);
}
private void button1_Click(object sender, EventArgs e){
// prepare your data here, -object, or string, or int, or whatever it is
var data = PrepareYourDataHere;
// invoke the event
OnSaveClicked(data);
Close();
}
}
Form1:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e){
// create an instance of Form2
var f2 = new Form2();
// add an event listener to SaveClicked event -which we have declared it in Form2
f2.SaveClicked += f2_SaveClicked;
f2.Show();
// or: f2.ShowDialog();
}
void f2_SaveClicked(object obj) {
// get data and use it here...
// any data which you pass in Form2.OnSaveClicked method, will be accessible here
}
}
UPDATE:
If you want to fire some events in form1, just after form2 closed, you can simply add a listener to Form2.FormClosed event:
// code from main form to create form2
private void button1_Click(object sender, EventArgs e) {
// Create a new instance of the Form2 class
Form2 settingsForm = new Form2();
settingsForm.FormClosed += SettingFormClosed;
// Show the settings form
settingsForm.Show();
string val = settingsForm.ReturnValue1;
MessageBox.Show(val);
}
void SettingFormClosed(object sender, FormClosedEventArgs e) {
// this method will be called automatically when form2 closed
}
here a sample how you can achieve this
//here I suppose that form1 is the mainform
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void UpdateMainForm(string updatedString)
{
//here you can update and invoke methods
//Once called you could raise events in your mainform
}
private void button1_Click(object sender, EventArgs e)
{
using (Form2 form2 = new Form2(this))
{
form2.ShowDialog();
}
}
}
Form2
public partial class Form2 : Form
{
private Form1 _mainForm1;
public Form2(Form1 mainForm1)
{
InitializeComponent();
_mainForm1 = mainForm1;
}
private void button1_Click(object sender, EventArgs e)
{
_mainForm1.UpdateMainForm( DateTime.Now.ToString());
}
}

Eventhandler does not fire when user control's button is clicked

I have a button from a user control and want it to notify my form when it is clicked. Here is how I do it. It does not work. Can someone tell me what is wrong with it?
In user Control
public event EventHandler clicked;
public string items;
InitializedData data = new InitializedData();
ArrayList list = new ArrayList();
public DataInput()
{
InitializeComponent();
clicked+= new EventHandler(Add_Click);
}
public void Add_Click(object sender, EventArgs e)
{
items = textBox1.Text.PadRight(15) + textBox2.Text.PadRight(15) + textBox3.Text.PadRight(15);
if (clicked != null)
{
clicked(this, e);
}
}
In Form1
UserControl dataInput= new UserControl();
public void OnChanged(){
dataInput.clicked += Notify;
MessageBox.Show("testing");
}
public void Notify(Object sender, EventArgs e)
{
MessageBox.Show("FIRE");
}
Thanks
The UserControls Button Click event should be assigned to Add_Click, I don't think you want to assign the UserControl clicked event to Add_Click
Try removing clicked += new EventHandler(Add_Click); from your UserControl and set the UserControls Button Click event to Add_Click so it will trigger clicked on you Form
Example:
UserControl:
public partial class UserControl1 : UserControl
{
public event EventHandler clicked;
public UserControl1()
{
InitializeComponent();
// your button
this.button1.Click += new System.EventHandler(this.Add_Click);
}
public void Add_Click(object sender, EventArgs e)
{
if (clicked != null)
{
// This will fire the click event to anyone listening
clicked(this, e);
}
}
}
Form:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// your usercontrol
userControl11.clicked += userControl11_clicked;
}
void userControl11_clicked(object sender, EventArgs e)
{
}
}

call event from form2 in form1

hi
call event from form2 in form1?
for example :
The following code into form2 :
private void Form2_Load(object sender, EventArgs e)
{
MessageBox.Show("http://stackoverflow.com");
}
What to write in a form1?
Why are you wanting to call the event? Will you know the sender and the Event Args?
Why don't you just create a public method in Form2 that Form1 is able to see?
how about form2.Form2_Load(this, null)
You can't call private members of a class from outside it.
You can change the accessibility to internal, which will make it visible within the assembly - if your form1 is in the same assembly.
Alternatively you can make it a public method, which would make it globally accessible.
However, you shouldn't call event handlers in such a manner - they are supposed to handle events that the declaring class raises.
For the sample code you gave, a better solution would be to create a public or internal method that can be called from this event handler:
private void Form2_Load(object sender, EventArgs e)
{
MyMethod();
}
public MyMethod()
{
MessageBox.Show("http://stackoverflow.com");
}
In order to call this method from form1, it needs to know about form2:
// in form1
Form frm2 = new Form2();
frm2.MyMethod();
You can't raise an Event from outside a class.
The convention is that you call a OnEventname method in the class. Usually this method is protected (can't only accessed from the class itself or others that inherit from it)
// in form1
private void Method1()
{
using (var form2 = new Form2())
{
form2.Show();
form2.RaiseLoadEvent(EventArgs.Empty);
}
}
// Create this method in form2
public void RaiseLoadEvent(EventArgs e)
{
OnLoad(this, e);
}
// The OnLoad method already exists in form 2
// But it usually looks like this
protected void OnLoad(EventArgs e)
{
var eh = LoadEventHandler;
if (eh != null)
{
eh(this, e);
}
}
But I don't suggest to raise the LoadEvent, because It is raised only once after the creation of the form. More usual is to react to the Load event to modify the form.
privat void Method1()
{
using (var form2 = new Form2())
{
// Add Event Handler
form2.Load += new EventHandler(form2_Load);
form2.ShowDialog();
}
// Allways remove Event Handler to avoid memory leaks
form2.Load -= new EventHandler(form2_Load);
}
private void form2_Load(object sender, EventArgs e)
{
form2.Text = "Hello from form1";
}
Form1 (the event publisher) should expose a separate, public event property for Form2 (the subscriber) to subscribe to.
For example: the form publishing the event will look like this:
public partial class Publisher : Form
{
public event PostUpdateHandler OnPostUpdate;
public Publisher()
{
InitializeComponent();
new Subscriber(this).Show();
}
private void button1_Click(object sender, EventArgs e)
{
if (OnPostUpdate != null)
{
OnPostUpdate(new PostUpdateArgs(textBox1.Text));
}
}
}
public delegate void PostUpdateHandler(PostUpdateArgs args);
public class PostUpdateArgs : EventArgs
{
public string UpdateText;
public PostUpdateArgs(string s)
{
UpdateText = s;
}
}
The subscribing form looks like this:
public partial class Subscriber : Form
{
public Subscriber()
{
InitializeComponent();
}
public Subscriber(Publisher publisher) : this()
{
publisher.OnPostUpdate += new PostUpdateHandler(publisher_OnPostUpdate);
}
private void publisher_OnPostUpdate(PostUpdateArgs args)
{
this.Form2_Load(null, null);
}
private void Subscriber_FormClosed(object sender, FormClosedEventArgs e)
{
this.Dispose();
}
private void Form2_Load(object sender, EventArgs e)
{
MessageBox.Show("http://stackoverflow.com");
}
}
When the user presses button1 on the publishing form, the subscribing form will execute the code associated with the delegate, resulting in a message box popping up with the message http://stackoverflow.com.

Categories