I need help in troubleshooting my code. I have 3 classes. Class 1 is a WinForm with Progressbar on it. Class 2 is where the event is fired. Class 3 is the EventArg for the progress. The program compiles with out any errors, but when I click the button, the progress bar does not move!.
namespace WindowsFormsApplication1
{
class Class1
{
//Declaring a delegate
public delegate void StatusUpdateHandler(object sender, ProgressEventArgs e);
//Declaraing an event
public event StatusUpdateHandler OnUpdateStatus;
public int recno;
public void Func()
{
//time consuming code
for (recno = 0; recno <= 100; recno++)
{
UpdateStatus(recno);
}
}
public void UpdateStatus(int recno)
{
// Make sure someone is listening to event
if (OnUpdateStatus == null) return; <--------------OnUpdateStatus is always null not sure why?
ProgressEventArgs args = new ProgressEventArgs(recno);
OnUpdateStatus(this, args);
}
}
}
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Class1 testClass;
public Form1()
{
InitializeComponent();
testClass = new Class1();
testClass.OnUpdateStatus += new Class1.StatusUpdateHandler(UpdateStatus);
}
public void button1_Click(object sender, EventArgs e)
{
Class1 c = new Class1();
c.Func();
}
public void UpdateStatus(object sender, ProgressEventArgs e)
{
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
progressBar1.Value = e.Recno;
}
}
}
namespace WindowsFormsApplication1
{
public class ProgressEventArgs : EventArgs
{
public int Recno { get; private set; }
public ProgressEventArgs(int recno)
{
Recno = recno;
}
}
}
You're using two different objects of Class1.
In button click handler, the object c is not the same as member object testClass. Use testClass in place of c and it shud work
public void button1_Click(object sender, EventArgs e)
{
testClass.Func();
}
You never added an event handler to c's event.
You did add a handler to testClass' event, but testClass is never used.
Related
I have a two classes.In one class i am creating and raising an event as follows :
CustomerAdd Class
public class CustomerAdd
{
public delegate void Done(object Sender, EventArgs e);
public event Done ListUpdated;
public void UpdateNewList()
{
//adding items to a generic List<T>,code removed as not relevant to post
//and raising the event afterwards
if (ListUpdated != null)
{
ListUpdated(this, EventArgs.Empty);
}
}
}
MyWindow Class
public class MyWindow
{
private void SaveToDisk()
{
CustomerAdd cuss = new CustomerAdd();
cuss.ListUpdated += new CustomerAdd.Done(DisplayDetails);
cuss.UpdateNewList();
}
private void DisplayDetails()
{
//other codes here
}
}
Now, when i call the SaveToDisk method from MyWIndow class,(as i am subscribing DisplayDetails method to the ListUpDated event) , DisplayDetails is not called. The debugger shows that ListUpdated is null. I have searched for hours and failed to come up with a solution.I followed this link but still ListUpdated is null. Any guidance/help would be highly appreciated.
It works:
using System;
namespace ConsoleApp2
{
class Program
{
public class CustomerAdd1
{
public delegate void Done(object Sender, EventArgs e);
public event Done ListUpdated;
public void UpdateNewList()
{
//adding items to a generic List<T>,code removed as not relevant to post
//and raising the event afterwards
if (ListUpdated != null)
{
ListUpdated(this, EventArgs.Empty);
}
}
}
public class CustomerAdd
{
public void SaveToDisk()
{
CustomerAdd1 cuss = new CustomerAdd1();
cuss.ListUpdated += new CustomerAdd1.Done(DisplayDetails);
cuss.UpdateNewList();
}
private void DisplayDetails(object Sender, EventArgs e)
{
Console.WriteLine("Test");
}
}
static void Main(string[] args)
{
var c = new CustomerAdd();
c.SaveToDisk();
Console.ReadLine();
}
}
}
Try this:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
CustomerReceive cr = new CustomerReceive();
cr.SaveToDisk();
}
}
public class CustomerAdd
{
public delegate void Done(object Sender, EventArgs e);
public event Done ListUpdated;
public void UpdateNewList()
{
//adding items to a generic List<T>,code removed as not relevant to post
//and raising the event afterwards
if (ListUpdated != null)
{
ListUpdated.Invoke(this, EventArgs.Empty);
}
}
}
public class CustomerReceive
{
public void SaveToDisk()
{
CustomerAdd cuss = new CustomerAdd();
cuss.ListUpdated += new CustomerAdd.Done(DisplayDetails);
cuss.UpdateNewList();
}
private void DisplayDetails(object Sender, EventArgs e)
{
int k = 0;
}
}
}
You need to do a good read on delegates and events because this is not working when there are more listeners
I have a progress bar which codes in below. I find this code from net. i really want to do when i click one button this button do some process and i count it.how can i understand when is there any changes in ReadExistingExcel fucnc this. This function is in other class and there are a lot of loop in this function
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Class1 yeni = new Class1();
yeni.Update();
}
public void UpdateMyProgressBar(int i)
{
progressBar1.Value=i;
backgroundWorker1.ReportProgress(i);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
this.Text = e.ProgressPercentage.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
}
other class
public class Class1
{
public void Update()
{
for (int i = 0; i < 100; i++)
{
Form1 ins = new Form1();
ins.UpdateMyProgressBar(i);
}
}
}
As your code stand now the Form1 class creates a new instance of Class1 which then, inside the Update method, creates 100 new instances of Form1. It's not getting a reference to the existing form. And that's your problem.
Try changing your Class1 code like this:
public class Class1
{
public Class1(Form1 form1)
{
_form1 = form1;
}
private Form1 _form1;
public void Update()
{
for (int i = 0; i < 100; i++)
{
_form1.UpdateMyProgressBar(i);
}
}
}
Then change Form1 like this:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Class1 yeni = new Class1(this);
yeni.Update();
}
public void UpdateMyProgressBar(int i)
{
backgroundWorker1.ReportProgress(i);
}
Well it sounds like you just need to have a public void to update the progressbar value.
public void UpdateProgressBar(int val)
{
progressBar1.Value = val;
}
This can then be called from your other classes by referring to your current class.
So if your current class is called Class1 and you want to call it from Class10 you would simply do
Class1.UpdateProgressBar(10);
I have a click event handler in class A with some logic. And now i want to access class A event handler from class B and do some logic so that class B event hadler logic fires first followed by class A event handler.
Example:
Class A
private void calculate_Click(object sender, System.EventArgs e)
{ this.MyMethod(); }
Class B
private void calculate_Click(object sender, System.EventArgs e)
{ // My new code.. (This should trigger first) this.MyMethod(); }
You may use event exposed by class A and consumed by class B like we do with Button class. Button exposes click event and in our form class we subscribe for click event being exposed by Button class.
I found this simple example for understanding here
using System;
namespace wildert
{
public class Metronome
{
public event TickHandler Tick;
public EventArgs e = null;
public delegate void TickHandler(Metronome m, EventArgs e);
public void Start()
{
// while (true) //uncomment this line if you want event to fire repeatedly
{
System.Threading.Thread.Sleep(3000);
if (Tick != null)
{
Tick(this, e);
}
}
}
}
public class Listener
{
public void Subscribe(Metronome m)
{
m.Tick += new Metronome.TickHandler(HeardIt);
}
private void HeardIt(Metronome m, EventArgs e)
{
System.Console.WriteLine("HEARD IT");
}
}
class Test
{
static void Main()
{
Metronome m = new Metronome();
Listener l = new Listener();
l.Subscribe(m);
m.Start();
}
}
}
Assuming class B has instance member A instanceOfClassA initilized properly with an instance of A:
private void calculate_Click(object sender, System.EventArgs e)
{
// My new code.. (This should trigger first)
instanceOfClassA.MyMethod();
// other code
}
You may also consider inheriting class B from A:
class B:A
{
private void calculate_Click(object sender, System.EventArgs e)
{
// My new code.. (This should trigger first)
this.MyMethod(); // will come from base class A implementation.
// other code
}
}
Any way to make this working code simpler ie the delegate { }?
public partial class Form1 : Form
{
private CodeDevice codeDevice;
public Form1()
{
InitializeComponent();
codeDevice = new CodeDevice();
//subscribe to CodeDevice.ConnectionSuccessEvent and call Form1.SetupDeviceForConnectionSuccessSate when it fires
codeDevice.ConnectionSuccessEvent += new EventHandler(SetupDeviceForConnectionSuccessState);
}
private void SetupDeviceForConnectionSuccessState(object sender, EventArgs args)
{
MessageBox.Show("It worked");
}
private void button1_Click(object sender, EventArgs e)
{
codeDevice.test();
}
}
public class CodeDevice
{
public event EventHandler ConnectionSuccessEvent = delegate { };
public void ConnectionSuccess()
{
ConnectionSuccessEvent(this, new EventArgs());
}
public void test()
{
System.Threading.Thread.Sleep(1000);
ConnectionSuccess();
}
}
WinForm event subscription to another class
How to subscribe to other class' events in c#?
If don't think you could simplyfy:
public event EventHandler ConnectionSuccessEvent = delegate { }
even in c#3 + you could only do
public event EventHandler ConnectionSuccessEvent = () => { }
However you could simplify
codeDevice.ConnectionSuccessEvent += new EventHandler(SetupDeviceForConnectionSuccessState);
to
codeDevice.ConnectionSuccessEvent += SetupDeviceForConnectionSuccessState;
I'm using 2 classes that contains buttons; I added their buttons in my main form, and now I want to do something when the user clicks on one of them. For example, if the user clicks on the button that's defined in class1, the text of all the buttons that are defined in class1 should change to "class1". Actually, I need to find the class of a button to change other variables in that class.
In your class, assign event handlers for the click event on the buttons so when you add them to the form and they're clicked the event handler will fire off inside of your class so you can access the class properties.
Otherwise, add the class reference to the button's Tag property.
class Class1
{
public Button MyButton { get; set; }
public Class1()
{
MyButton = new Button();
MyButton.Click += new EventHandler(MyButton_Click);
}
void MyButton_Click(object sender, EventArgs e)
{
//Do code here
}
}
public partial class Form1 : Form
{
Class1 c1 = new Class1();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
c1.MyButton.Width = 100;
c1.MyButton.Height = 100;
c1.MyButton.Top = 0;
c1.MyButton.Left = 0;
this.Controls.Add(c1.MyButton);
}
OR
class Class1 : IButtonClass
{
public Button MyButton { get; set; }
public Class1()
{
MyButton = new Button();
MyButton.Tag = this;
}
public void DoSoemthing()
{
//Do something
}
}
interface IButtonClass
{
void DoSoemthing();
}
public partial class Form1 : Form
{
Class1 c1 = new Class1();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
c1.MyButton.Width = 100;
c1.MyButton.Height = 100;
c1.MyButton.Top = 0;
c1.MyButton.Left = 0;
this.Controls.Add(c1.MyButton);
c1.MyButton.Click += new EventHandler(MyButton_Click);
}
void MyButton_Click(object sender, EventArgs e)
{
IButtonClass c = ((Button)sender).Tag as IButtonClass;
c.DoSoemthing();
}
}
In the button click event, you can try
void button_Click(object sender, EventArgs e)
{
Console.WriteLine((sender as Button).Parent.Name);
}