I have null exception error on sending ValueChanged() event when creating this custom control and testing it in a client:
Source of custom control:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace customevent
{
[DefaultEvent("ValueChanged")]
public partial class UserControl1 : UserControl
{
private int m_value;
public delegate void ValueChangedHandler();
[Category("Action")]
[Description("Value changed.")]
public event ValueChangedHandler ValueChanged;
public int Value
{
get { return m_value; }
set {
m_value = value;
ValueChanged();
}
}
public UserControl1()
{
InitializeComponent();
}
public UserControl1(int iValue)
{
this.Value = iValue;
InitializeComponent();
}
}
}
Then in test form:
private void Form1_Load(object sender, EventArgs e)
{
userControl11.Value = 100;
}
private void userControl11_ValueChanged()
{
MessageBox.Show(userControl11.Value.ToString());
}
Or instead of form_load, do this in constructor:
private void InitializeComponent()
{
this.userControl11 = new customevent.UserControl1(100);
You should declare the event handling as this:
public event EventHandler ValueChanged;
protected virtual void OnValueChanged(object sender, EventArgs e)
{
if (ValueChanged != null)
{
ValueChanged(sender, e);
}
}
public int Value
{
get { return m_value; }
set {
if (m_value == value) return;
m_value = value;
OnValueChanged(this, EventArgs.Empty);
}
}
PS: there is an interface INotifyPropertyChanged, you should use this instead to comply with standard .NET databinding rules.
You're not checking for nulls:
public int Value
{
get { return m_value; }
set {
m_value = value;
if(ValueChanged != null)
{
ValueChanged();
}
}
}
Furthermore, you're also not hooking into this event in your Form:
private void Form1_Load(object sender, EventArgs e)
{
userControl1.ValueChanged += userControl11_ValueChanged;
userControl11.Value = 100;
}
private void userControl11_ValueChanged()
{
MessageBox.Show(userControl11.Value.ToString());
}
Simon got you almost there:
protected virtual void OnValueChanged(object sender, EventArgs e)
{
var tmp = ValueChanged;
if (tmp != null)
{
tmp(sender, e); // With the tmp, we won't explode if a subscriber changes the collection of delegates underneath us.
}
}
Related
I would like to create a simple custom control (actually a type of button). I have created the control but the step I am missing is how to add the binding. The control code I have looks like this:
public partial class PopUpButton : UserControl
{
public PopUpButton()
{
InitializeComponent();
_checked = false;
DrawButton();
}
public delegate void ChangedEventHandler(object sender, EventArgs e);
public event ChangedEventHandler OnValueChanged;
private bool _checked;
private String _text;
private void UserControl1_Resize(object sender, EventArgs e)
{
DrawButton();
}
[Bindable(true)]
public bool Checked
{
get
{
return _checked;
}
set
{
_checked = value;
DrawButton();
if (OnValueChanged != null)
{
OnValueChanged.Invoke(this, new EventArgs());
}
}
}
[Bindable(true)]
public String DisplayText
{
get
{
return _text;
}
set
{
_text = value;
DrawButton();
}
}
private void DrawButton()
{
// do some stuff
}
private void PopUpButton_Click(object sender, EventArgs e)
{
_checked = !_checked;
DrawButton();
if (OnValueChanged != null)
{
OnValueChanged.Invoke(this, new EventArgs());
}
}
}
The call to bind to the control looks like this:
regControl1.DataBindings.Clear();
regControl1.DataBindings.Add("Checked", CustomButton1, "Checked");
I know that I need to define a data source and member but cannot see how to implement this. When the above binding is called then regControl1 updates with the value of "Checked" however the function "OnValueChanged" is always null so the binding has failed, thus when "Checked" changes "regControl1" is not updated.
Ideas anyone?
Finally got something working. This solution handles a click both on the body and on the label and re-sizes the component during design. I was almost there but hope this helps:
public partial class PopUpButton : UserControl, INotifyPropertyChanged
{
public PopUpButton()
{
InitializeComponent();
_checked = false;
DrawButton();
}
private bool _checked;
private String _text;
public event PropertyChangedEventHandler PropertyChanged;
public event EventHandler ButtonClick;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
protected void Button_Click(object sender, EventArgs e)
{
_checked = !_checked;
DrawButton();
NotifyPropertyChanged("Checked");
if (this.ButtonClick != null)
this.ButtonClick(this, e);
}
private void UserControl1_Resize(object sender, EventArgs e)
{
DrawButton();
}
[Bindable(true)]
public bool Checked
{
get
{
return _checked;
}
set
{
_checked = value;
DrawButton();
NotifyPropertyChanged("Checked");
}
}
[Bindable(true)]
public String DisplayText
{
get
{
return _text;
}
set
{
_text = value;
DrawButton();
}
}
private void HandleClick( )
{
_checked = !_checked;
DrawButton();
NotifyPropertyChanged("Checked");
}
private void DrawButton()
{
//do some drawing stuff here
}
private void PopUpButton_Resize(object sender, EventArgs e)
{
DrawButton();
}
}
I'm struggling to implement the injection of dependencies using ASP.net. I have created a simple project in winforms which uses the MVP Passive View pattern. I see lots of variations of this pattern online. Many examples I see have the View responsible for instantiating the Presenter. Others have the Presenter create the View. I chose to let a separate winforms project run first and on the click of a button, create my View, Model and Presenter and have the view passed in to the Presenters constructor. This let me avoid direct references between the three layers such that they only kept a reference to a Library of Interfaces. So far so good and everything worked as hoped. I had heard that if I had managed to keep the View as "dumb" as possible that moving to ASP.net would not be too difficult since the main logic presided in the Presenter.
My next move was to recreate the solution in ASP.net webforms and just replace the UI/View with a webform in whoch the code-behind implemented my IView Interface. All my classes successfully compiled without issue but when I run the program I get a NullReferenceException :object reference not set to an instance of an object. This happens as the Presenter tries to set the view property of a textbox. It seems like the textbox has not been created. If I compare the start sequence of the webforms app with the winforms app then I see that the winforms app runs through the View when it is created and registers each control and property. This does not happen with the webform even though I use the same approach for both.
Here is the separate webform which loads first:
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using POCOClassLibrary;
using InterfaceLibrary;
using AppointmentModel;
using AppointmentsPresenter;
using WebFormMVP;
namespace WebDriver
{
public partial class WebDriver : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnLaunch_Click(object sender, EventArgs e)
{
IAppointmentView view = new frmAppointmentView();
IAppointmentModel<Appointment> model = new AppointmentsModel();
new AppointmentPresenter(view, model);
view.Show();
}
}
}
This loads and the button appears, next on clicking it reaches the Presenter class (not all shown here):
namespace AppointmentsPresenter
{
//The Presenter is the go-between for the View and Model. It sets the properties in the View to be displayed and
//Stores and Gets the data from the Model. It responds to events raised by the View.
public class AppointmentPresenter
{
private readonly IAppointmentView _view; //references the View Interface
private readonly IAppointmentModel<Appointment> _model; //references the Model Interface
/// <summary>
/// The List of Appointments is created and stored in the Model.
/// In reality we would be using a Database and not a List<>.
/// </summary>
private List<Appointment> appointments;
//maintenace of state:
private int currentIndex = 0;
private bool isNew = true;
private string navigationstatus = "next";
///Presenter constuctor which allows us to pass in the View and Model as interfaces - exposing their events,
/// methods and properties.
public AppointmentPresenter(IAppointmentView view, IAppointmentModel<Appointment> model) //dependencies passed into contructor
{
this._view = view;
this._model = model;
Initialize();
}
private void Initialize()
{
appointments = _model.CreateList(); //Creates and returns List of Appointments in the Model
//lets us manipulate the List that the Model creates.
_view.SaveAppointment += Save_Appointment; //Subscribe to the View events.
_view.NewAppointment += New_Appointment;
_view.PreviousAppointment += Previous_Appointment;
_view.NextAppointment += Next_Appointment;
_view.YesButtonClick += YesButtonClicked;
_view.NoButtonClick += NoButtonClicked;
BlankAppointment();
_view.StatusChange = "Ready";
}
private void BlankAppointment()
{
_view.AppointmentName = string.Empty;
_view.Priority = "Low";
_view.StartDate = null;
_view.DueDate = null;
_view.CompletionDate = null;
_view.Completed = false;
}
When it reaches the BlankAppointment() method and tries to set the _view.AppointmentName property is when things go awry and the NullReferenceException is thrown.
Here is some of the View, I have tried to remove the majority of logic outside and just implement properties and events here:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using InterfaceLibrary;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition;
namespace WebFormMVP
{
public partial class frmAppointmentView : System.Web.UI.Page, IAppointmentView
{
public string AppointmentName
{
get { return txtAppointment.Text; }
set { txtAppointment.Text = value; }
}
public string Priority
{
get { return cboPriority.Text; }
set { cboPriority.Text = value; }
}
public string StartDate
{
get { return txtStartDate.Text; }
set { txtStartDate.Text = value; }
}
public string DueDate
{
get { return txtDueDate.Text; }
set { txtDueDate.Text = value; }
}
public string CompletionDate
{
get { return txtCompletionDate.Text; }
set { txtCompletionDate.Text = value; }
}
public bool Completed
{
get { return chkCompleted.Checked; }
set { chkCompleted.Checked = value; }
}
public bool isDirty { get; set; }
public bool NewButtonVisible
{
set { btnNew.Visible = value; }
}
public bool SaveButtonVisible
{
set { btnSave.Visible = value; }
}
public bool NextButtonVisible
{
set { btnNext.Visible = value; }
}
public bool PreviousButtonVisible
{
set { btnPrevious.Visible = value; }
}
public bool YesButtonVisible
{
set { btnYes.Visible = value; }
}
public bool NoButtonVisible
{
set { btnNo.Visible = value; }
}
public string StatusChange
{
set { lblStatus.Text = value; }
}
public event EventHandler<EventArgs> NewAppointment;
public event EventHandler<EventArgs> NextAppointment;
public event EventHandler<EventArgs> NoButtonClick;
public event EventHandler<EventArgs> PreviousAppointment;
public event EventHandler<EventArgs> SaveAppointment;
public event EventHandler<EventArgs> YesButtonClick;
public void Show()
{
this.Show();
}
protected void Page_Load(object sender, EventArgs e)
{
this.isDirty = false;
}
private void btnSave_Click(object sender, EventArgs e)
{
if (SaveAppointment != null)
{
SaveAppointment(this, EventArgs.Empty);
}
}
private void btnNew_Click(object sender, EventArgs e)
{
if (NewAppointment != null)
{
NewAppointment(this, EventArgs.Empty);
}
}
private void btnPrevious_Click(object sender, EventArgs e)
{
if (PreviousAppointment != null)
{
PreviousAppointment(this, EventArgs.Empty);
}
}
private void btnNext_Click(object sender, EventArgs e)
{
if (NextAppointment != null)
{
NextAppointment(this, EventArgs.Empty);
}
}
private void btnYes_Click(object sender, EventArgs e)
{
if (YesButtonClick != null)
{
YesButtonClick(this, EventArgs.Empty);
}
}
private void btnNo_Click(object sender, EventArgs e)
{
if (NoButtonClick != null)
{
NoButtonClick(this, EventArgs.Empty);
}
}
private void txtAppointment_TextChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
private void cboPriority_SelectedIndexChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
private void txtStartDate_TextChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
private void txtDueDate_TextChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
private void txtCompletionDate_TextChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
private void chkCompleted_CheckedChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
}
}
Form my searches so far it seems like there may be a problem with implementing the injection into the Presenters constructor in webforms and that I would need to override the PageHandler class to resolve the dependencies however the examples I have looked at so far have the Presenter being created first by the View. I would like to avoid this if at all possible and use a separate webform Page to instantiate the Model, View, Presenter and resolve the dependencies this way.
Apologies if I haven't been clear - I am very wet behind the ears with both MVP and ASP.net Webforms. Any advice would be greatly appreciated as I am pretty confused as to how I might solve this puzzle. ;D
I'm trying to understand the lock mechanism.
if I have multiple events to lock on different value should I use an object lock for each?
More serious code added:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
namespace ValueChangeOnEventForm
{
public partial class Form1 : Form
{
private Test_Onchange DataSource;
Thread Task1;
private bool Flag_Stop_Task1;
public Form1()
{
InitializeComponent();
graph1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
graph1.ChartAreas[0].AxisX.IsLabelAutoFit = true;
graph1.ChartAreas[0].AxisX.ScaleView.Size = 100;
graph2.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
graph2.ChartAreas[0].AxisX.IsLabelAutoFit = true;
graph2.ChartAreas[0].AxisX.ScaleView.Size = 100;
DataSource = new Test_Onchange();
DataSource.ValueChanged += new EventHandler(EventValueChange);//Value input info
DataSource.SecondValueChange += new EventHandler(EventSecondValueChange);//second value
Task1 = new Thread(new ThreadStart(Task_1));//create the thread
Task1.Start();//start the thread
}
protected virtual void EventSecondValueChange(object sender, EventArgs e)
{
double valueMAX = 0, size = 0;
if (graph1.InvokeRequired)
{
graph1.Invoke(new MethodInvoker(delegate { graph1.Series["ValueOnGraph"].Points.AddY(DataSource.Value); }));
graph1.Invoke(new MethodInvoker(delegate { valueMAX = graph1.ChartAreas[0].AxisX.Maximum; }));
graph1.Invoke(new MethodInvoker(delegate { size = graph1.ChartAreas[0].AxisX.ScaleView.Size; }));
if (valueMAX - 10 > size)
{
graph1.Invoke(new MethodInvoker(delegate { graph1.ChartAreas[0].AxisX.ScaleView.Scroll(graph1.ChartAreas[0].AxisX.Maximum); }));
graph1.Invoke(new MethodInvoker(delegate { graph1.Series["ValueOnGraph"].Points.RemoveAt(0); }));
}
}
}
protected virtual void EventValueChange(object sender, EventArgs e)
{
double valueMAX=0,size=0;
if (graph2.InvokeRequired)
{
graph2.Invoke(new MethodInvoker(delegate { graph2.Series["ValueOnGraph2"].Points.AddY(DataSource.Secondvalue); }));
graph2.Invoke(new MethodInvoker(delegate { valueMAX = graph2.ChartAreas[0].AxisX.Maximum; }));
graph2.Invoke(new MethodInvoker(delegate { size = graph2.ChartAreas[0].AxisX.ScaleView.Size; }));
if (valueMAX - 10 > size)
{
graph2.Invoke(new MethodInvoker(delegate { graph2.ChartAreas[0].AxisX.ScaleView.Scroll(graph2.ChartAreas[0].AxisX.Maximum); }));
graph2.Invoke(new MethodInvoker(delegate { graph2.Series["ValueOnGraph2"].Points.RemoveAt(0); }));
}
}
}
private void Task_1()
{
while (!Flag_Stop_Task1)
{
Random RandVal = new Random();
Random RandVal2 = new Random();
int Value = RandVal.Next(0, 100);
int SecondValue = RandVal2.Next(50, 200);
DataSource.Value = Value;
DataSource.Secondvalue = SecondValue;
Thread.Sleep(100);
}
Flag_Stop_Task1 = false;
}
private void btn_StopTask_1_Click(object sender, EventArgs e)
{
Flag_Stop_Task1 = true;
}
}
}
And then
namespace ValueChangeOnEventForm
{
class Test_Onchange
{
private int value;
private int secondvalue;
protected object _lock = new object();
public event System.EventHandler ValueChanged;
public event System.EventHandler SecondValueChange;
protected virtual void OnValueChange()
{
lock (this._lock)
{
EventHandler eventvaluechange = ValueChanged;
if (eventvaluechange != null)
eventvaluechange(this, EventArgs.Empty);
}
}
protected virtual void OnSecondValueChange()
{
lock (this._lock)
{
EventHandler eventvaluechange = SecondValueChange;
if (eventvaluechange != null)
eventvaluechange(this, EventArgs.Empty);
}
}
public int Value
{
get { return this.value; }
set
{
if (value != this.value)
{//if value changed enter
this.value = value;
OnValueChange();
}
}
}
public int Secondvalue
{
get { return this.secondvalue; }
set
{
if (value != this.secondvalue)
{//if value changed enter
this.secondvalue = value;
OnSecondValueChange();
}
}
}
}
}
Do I need two lock (lock1 and lock2 object or only one for both value and secondvalue....?
Thanks a lot.
Update
Ok let's do it so.
I'm using beckhoff PLC which are real time Task PLC. and I'm reading two value on it when the value change. like this:
Form1 Class:
namespace RealTimeLock
{
using Beckhoff.App.Ads.Core;
using Beckhoff.App.Ads.Core.Plc;
using TwinCAT.Ads;
using System.IO;
public partial class Form1 : Form
{
private PLC PLCData;
public Form1()
{
InitializeComponent();
}
public Form1(IBAAdsServer _adsServer)
: this()
{
PLCData = new PLC(_adsServer);
PLCData.ErrorBoolChanged += new EventHandler(EventErrorChanged);//error info
PLCData.ForceValChanged += new EventHandler(EventForceChanged);//Force input info
}
protected virtual void EventErrorChanged(object sender, EventArgs e)
{
//state of error PLC
lv_ErrorInfo.Text = "PLC Error num : " + PLCData.i_ErrorID.ToString();
}
protected virtual void EventForceChanged(object sender, EventArgs e)
{//modify graphical data PLC Force data
lv_ForceInfo.Text = PLCData.i_ForceVal.ToString();
c_graphForceIN.Series["ForceData"].Points.AddY(PLCData.i_ForceVal);
if (c_graphForceIN.ChartAreas[0].AxisX.Maximum - 10 > c_graphForceIN.ChartAreas[0].AxisX.ScaleView.Size)
{
c_graphForceIN.ChartAreas[0].AxisX.ScaleView.Scroll(c_graphForceIN.ChartAreas[0].AxisX.Maximum);
c_graphForceIN.Series["ForceData"].Points.RemoveAt(0);
}
}
}
}
Error ID and Force change showed in Form1 label lv_ErrorID and lv_Force and graphForceIN add point.
The events handler on the other side (PLC class) looks like this:
PLC Class:
namespace RealTimeLock
{
using Beckhoff.App.Ads.Core;
using Beckhoff.App.Ads.Core.Plc;
using TwinCAT.Ads;
using System.IO;
public partial class Form1 : Form
{
private PLC PLCData;
public Form1()
{
InitializeComponent();
}
public Form1(IBAAdsServer _adsServer)
: this()
{
PLCData = new PLC(_adsServer);
PLCData.ErrorBoolChanged += new EventHandler(EventErrorChanged);//error info
PLCData.ForceValChanged += new EventHandler(EventForceChanged);//Force input info
}
protected virtual void EventErrorChanged(object sender, EventArgs e)
{
//state of error PLC
lv_ErrorInfo.Text = "PLC Error num : " + PLCData.i_ErrorID.ToString();
}
protected virtual void EventForceChanged(object sender, EventArgs e)
{//modify graphical data PLC Force data
lv_ForceInfo.Text = PLCData.i_ForceVal.ToString();
c_graphForceIN.Series["ForceData"].Points.AddY(PLCData.i_ForceVal);
if (c_graphForceIN.ChartAreas[0].AxisX.Maximum - 10 > c_graphForceIN.ChartAreas[0].AxisX.ScaleView.Size)
{
c_graphForceIN.ChartAreas[0].AxisX.ScaleView.Scroll(c_graphForceIN.ChartAreas[0].AxisX.Maximum);
c_graphForceIN.Series["ForceData"].Points.RemoveAt(0);
}
}
}
}
Does it seem to be correct coding for you guys? and while I have a real time task running there do I need to lock variables and if so, do I need two lock or only one??
Thanks for your remark on this!!
I'm a new beginner on this topic. I created a c# win form. In this form, I have two textboxes and one label. What I want to do is create a delegate event to track the textbox's change and add up two numbers from textbox1 and textbox2. The label will show the result automatically. Hope someone can provide me a example for this, thank you so much! There is something I have right now,
events.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Project3
{
public delegate void Calculate(int obj1, int obj2);
public class events
{
int result;
public int Add(int x, int y)
{
result = x + y;
return result;
}
}
}
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Project3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
label1.Text ="";
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
}
}
If you just want to learn how to delegate the result into the label, and learn the delegate and event, here is a sample you may want to try and analyze for learning purposes:
Sample 1:
public delegate int CalculateEventHandler(object obj1, object obj2);
public partial class Form1 : Form
{
public event CalculateEventHandler Calculate;
private string OnCalculate(string text1, string text2)
{
string result = "0";
if (this.Calculate != null)
{
result = this.Calculate(this.textBox1.Text, this.textBox2.Text).ToString();
}
return result;
}
public Form1()
{
this.InitializeComponent();
this.InitializeEvent();
}
private void InitializeEvent()
{
this.Calculate += Form1_Calculate;
}
private int Form1_Calculate(object obj1, object obj2)
{
int a = 0;
int b = 0;
int.TryParse(obj1.ToString(), out a);
int.TryParse(obj2.ToString(), out b);
return a + b;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
this.label1.Text = OnCalculate(this.textBox1.Text, this.textBox2.Text);
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
this.label1.Text = OnCalculate(this.textBox1.Text, this.textBox2.Text);
}
}
Sample 2:
Form1.cs
public partial class Form1 : Form
{
public Form1()
{
this.InitializeComponent();
this.InitializeEvent();
}
private void InitializeEvent()
{
Event.Calculate += Event_Calculate;
}
private int Event_Calculate(object obj1, object obj2)
{
int x = 0;
int y = 0;
int.TryParse(obj1.ToString(), out x);
int.TryParse(obj2.ToString(), out y);
return Event.Add( x, y );
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
this.label1.Text = Event.OnCalculate(this.textBox1.Text, this.textBox2.Text).ToString();
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
this.label1.Text = Event.OnCalculate(this.textBox1.Text, this.textBox2.Text).ToString();
}
}
Event.cs
public delegate int CalculateEventHandler(object obj1, object obj2);
public class Event
{
static public event CalculateEventHandler Calculate;
static public int Add(int x, int y)
{
int result = x + y;
return result;
}
static public int OnCalculate( object obj1, object obj2 )
{
int result = 0;
if( Calculate != null )
{
result = Calculate(obj1, obj2);
}
return result;
}
}
NOTE: The above examples are by no means a good approach to calculate two values, this just serves as an example. The disadvantage of this approach would lead you to somehow spaghetti code, going back and forth to where the logic is going.
There is a simple solution
private void textBox1_TextChanged(object sender, EventArgs e)
{
try
{
if (textBox2.Text == string.Empty)
{
//textBox2.Text = (0).ToString();
label1.Text = ( Convert.ToInt32(textBox1.Text)).ToString();
}
else if (textBox1.Text == string.Empty)
{
label1.Text = (Convert.ToInt32(textBox2.Text)).ToString();
}
else
{
label1.Text = (Convert.ToInt32(textBox1.Text) + Convert.ToInt32(textBox2.Text)).ToString();
}
}
catch (Exception e3)
{
MessageBox.Show(e3.Message);
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
try
{
if (textBox2.Text == string.Empty)
{
//textBox2.Text = (0).ToString();
label1.Text = (Convert.ToInt32(textBox1.Text)).ToString();
}
else if (textBox1.Text == string.Empty)
{
label1.Text = (Convert.ToInt32(textBox2.Text)).ToString();
}
else
{
label1.Text = (Convert.ToInt32(textBox1.Text) + Convert.ToInt32(textBox2.Text)).ToString();
}
}
catch (Exception e3)
{
MessageBox.Show(e3.Message);
}
}
This question is related to c#.The scenario is that when i click the button the operations like File reading,Data manipulation ,and file dumping are going to be happened.After the completion of each operation i will update the status(i.e,File reading completed,data manipulation completed) in the label which is in UI(FORM-frmTesting)
The button click event is
namespace frmTesting
{
public partial class Form1 : Form
{
private void button1_Click_1(object sender, EventArgs e)
{
class1 l_objClass1 = new class1();
l_objClass1.DoOperation();
}
}
public class class1
{
public int DoOperation()
{
ReadTextFile();
ParsingData();
SaveTextFile();
return 0;
}
private int ReadTextFile()
{
//Read the text File
return 0;
}
private int ParsingData()
{
// Data manipulation
return 0;
}
private int SaveTextFile()
{
// save the file
return 0;
}
}
}
Is it possible by using Delegates and Events....if you have any queries plz revert back me
You'll have to modify class1 to broadcast events that other classes can listen to:
public class class1
{
// Not necessary, but will allow you to add custom EventArgs later
public delegate void StatusChangedEventHandler(object sender, EventArgs e);
public event StatusChangedEventHandler FileRead;
public event StatusChangedEventHandler FileParsed;
public event StatusChangedEventHandler FileSaved;
public int DoOperation()
{
ReadTextFile();
ParsingData();
SaveTextFile();
return 0;
}
private int ReadTextFile()
{
//Read the text File
OnFileRead(EventArgs.Empty);
return 0;
}
private int ParsingData()
{
// Data manipulation
OnFileParsed(EventArgs.Empty);
return 0;
}
private int SaveTextFile()
{
// save the file
OnFileSaved(EventArgs.Empty);
return 0;
}
protected virtual void OnFileRead(EventArgs e)
{
if(FileRead != null)
FileRead(this, e);
}
protected virtual void OnFileParsed(EventArgs e)
{
if(FileParsed != null)
FileParsed(this, e);
}
protected virtual void OnFileSaved(EventArgs e)
{
if(FileSaved != null)
FileSaved(this, e);
}
}
And then have your form listen for those events and change its label appropriately:
public partial class Form1 : Form
{
private void button1_Click_1(object sender, EventArgs e)
{
class1 l_objClass1 = new class1();
l_objClass1.FileRead +=
delegate { lblStatus.Text = "File Read..."; };
l_objClass1.FileParsed +=
delegate { lblStatus.Text = "File Parsed..."; };
l_objClass1.FileSaved +=
delegate { lblStatus.Text = "File Saved..."; };
l_objClass1.DoOperation();
}
}
The short answer is yes. You add events to class1 and add handlers to Form1 with the appropriate logic. Below is a sample of how to do this
public partial class Form1 : Form
{
private void button1_Click_1(object sender, EventArgs e)
{
class1 obj = new class1();
obj.FileReadingComplete += HandleFileReadingComplete;
obj.DataManipulationComplete += HandleDataManipulationComplete;
obj.DoOperation();
obj.FileReadingComplete -= HandleFileReadingComplete;
obj.DataManipulationComplete -= HandleDataManipulationComplete;
}
private void HandleFileReadingComplete(object sender, EventArgs args){
//code here
}
private void HandleDataManipulationComplete(object sender, EventArgs args)
{
//code here
}
}
public class class1
{
public event EventHandler FileReadingComplete;
public event EventHandler DataManipulationComplete;
public int DoOperation()
{
ReadTextFile();
OnFileReadingComplete();
ParsingData();
OnDataManipulationComplete();
SaveTextFile();
return 0;
}
private int ReadTextFile()
{
//Read the text File
return 0;
}
private int ParsingData()
{
// Data manipulation
return 0;
}
private int SaveTextFile()
{
// save the file
return 0;
}
public void OnFileReadingComplete()
{
EventHandler handler = FileReadingComplete;
if (handler != null) {
handler(this, EventArgs.Empty);
}
}
public void OnDataManipulationComplete()
{
EventHandler handler = DataManipulationComplete;
if (handler != null) {
handler(this, EventArgs.Empty);
}
}
}