Custom Events and Delegates .... is it possible to explain without

  • Thread starter Russell Smallwood
  • Start date
R

Russell Smallwood

Referring to function pointers? To those of us who are jumping into OOP
without the benefit of a past life as a C++ programmer, there seems to
be a disconnect in how this concept is explained.

I was just at the bookstore and EVERY SINGLE BOOK I picked up began with
comparing delegates to function pointers and then continues as if that
clarifies things.

Okay, so how about some help with this topic. Maybe we can put together
a thread that will help others in the future (including me).

I'm currently working an application that has, what I think, is a
perfect example of how a custom event should be utilized, however, I'm
95% of the way there but just can't get the last bit. Can we boil this
all down to something very very simple....say....

We have a class that does nothing but writes events to a log file:

public class writeLog
{
private string _message;

public writeLog (string message)
{
this._message=message;

}

public void publish()
{
do stuff here to write
the message to a text
file
}
}


Very simple. Okay, let's say we call this little ditty throughout our
application like this:

writeLog mymessage = new writeLog("I just did something great!");
mymessage.publish();

Pretty straight forward, your logging thingy is logging away nicely.
Being called from everywhere, you're amassing a pretty hefty log file
when you suddenly realize that it would be helpful to display the log
information as it's being written in a rich text control on your
application's main form:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;

namespace myapp
{

public class MainForm : System.Windows.Forms.Form
{

private System.Windows.Forms.RichTextBox rt_log;

private System.ComponentModel.Container components = null;

public MainForm()
{
InitializeComponent();
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code


static void Main()
{
Application.Run(new MainForm());
}
}
}

So, thus begins a very simple discussion on how to wire this
alltogether. I know that I'll need to add an event handler and an event
to my log writer class (I think), then call the event, but how do I hook
into this event in my form?

-r


































--
Russell Smallwood
Relatia Software Corporation

Finally! Time and Billing in GoldMine
www.relatia.net
 
G

Guest

A Delegate is Like an abstract Method constructor...It really just defines what TYPE the event returns(if any) and what parameters are required for the event.

An Event is defined within your class with its return values and parameters pulled in from the delegate when you go t
use the event

You trigger the event within your code only if someone has registered interest in it.

Here is your example.
//Q&D by Mike in Paradise re Delegates and events.
using System
using System.Drawing
using System.Collections
using System.ComponentModel
using System.Windows.Forms
using System.Data

namespace EventTes

/// <summary
/// Delegate is really just an Abstract definition of what your event metho
/// will be
/// NOTE
///
/// 1.. Void for return but could have a valu
/// 2.. Parameters for the Event Handle
/// </summary
public delegate void MessageEventHandler (object sender, MessageEventArgs e)
/// <summary
/// Summary description for Form1
/// </summary
public class Form1 : System.Windows.Forms.For

private WriteLog writeLog
private System.Windows.Forms.Button button1
private System.Windows.Forms.RichTextBox richTextBox1
private System.Windows.Forms.TextBox textBox1
/// <summary
/// Required designer variable
/// </summary
private System.ComponentModel.Container components = null
public Form1(

/
// Required for Windows Form Designer suppor
/
InitializeComponent()
writeLog = new WriteLog()
//Here is where you must register your interest in the class even
//type in this line for yourself and watch it create the parameter
writeLog.OnNewMessage +=new MessageEventHandler(writeLog_OnNewMessage)


/// <summary
/// Clean up any resources being used
/// </summary
protected override void Dispose( bool disposing

if( disposing

if (components != null)

components.Dispose()


base.Dispose( disposing )


#region Windows Form Designer generated cod
/// <summary
/// Required method for Designer support - do not modif
/// the contents of this method with the code editor
/// </summary
private void InitializeComponent(

this.button1 = new System.Windows.Forms.Button()
this.richTextBox1 = new System.Windows.Forms.RichTextBox()
this.textBox1 = new System.Windows.Forms.TextBox()
this.SuspendLayout()
//
// button
//
this.button1.Location = new System.Drawing.Point(32, 40)
this.button1.Name = "button1"
this.button1.TabIndex = 0
this.button1.Text = "Send"
this.button1.Click += new System.EventHandler(this.button1_Click)
//
// richTextBox
//
this.richTextBox1.Location = new System.Drawing.Point(48, 128)
this.richTextBox1.Name = "richTextBox1"
this.richTextBox1.Size = new System.Drawing.Size(192, 96)
this.richTextBox1.TabIndex = 2
this.richTextBox1.Text = "richTextBox1"
//
// textBox
//
this.textBox1.Location = new System.Drawing.Point(120, 40)
this.textBox1.Name = "textBox1"
this.textBox1.TabIndex = 3
this.textBox1.Text = "<MESSAGE>"
//
// Form
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13)
this.ClientSize = new System.Drawing.Size(292, 266)
this.Controls.Add(this.textBox1)
this.Controls.Add(this.richTextBox1)
this.Controls.Add(this.button1)
this.Name = "Form1"
this.Text = "Form1"
this.ResumeLayout(false)


#endregio

/// <summary
/// The main entry point for the application
/// </summary
[STAThread
static void Main()

Application.Run(new Form1())

/// <summary
/// Method: this where you will recieve the event..
/// </summary
/// <param name="sender"></param
/// <param name="e"></param
private void writeLog_OnNewMessage(object sender, MessageEventArgs e

this.richTextBox1.Text += e.Message+Environment.NewLine


private void button1_Click(object sender, System.EventArgs e

writeLog.Message(this.textBox1.Text)


/// <summary
/// Class: Write lo
/// </summary
public class WriteLo
{
private string _message
//Note: WHen you trigger this event it will go to the
//Delegate to get the methods Contructor eg return value and Parameter
[field: NonSerialized
public event MessageEventHandler OnNewMessage;

//contructor
public WriteLog ()
{
}
//Method to Receive a message
public void Message (string message)
{
this._message=message;
//Check if anyone Registered Interest
if (this.OnNewMessage != null)
{
OnNewMessage(this,new MessageEventArgs(message));
}
}

public void publish()
{
}
}
/// <summary>
/// Class: Set up a class based on system event arguments to pass info with..
/// </summary>
public class MessageEventArgs: System.EventArgs
{
string message;
/// <summary>
/// Property: Use to get your message
/// </summary>
public string Message
{
get {return message;}
}
public MessageEventArgs (String message)
{
this.message = message;
}
}
}
 
R

Russell Smallwood

Thanks a bunch, this was helpful but I'm still having trouble getting my
stuff wired together. Here's my main form:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;

namespace autofolio
{

public class MainForm : System.Windows.Forms.Form
{
private writeLog mylog;
private System.Windows.Forms.Label lbl_program_status;
private System.Windows.Forms.MainMenu mainMenu1;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem menuItem2;
private System.Windows.Forms.MenuItem menuItem5;
private System.Windows.Forms.MenuItem menuItem6;
private System.Windows.Forms.MenuItem menuItem7;
private System.Windows.Forms.MenuItem menuItem8;
private System.Windows.Forms.MenuItem menuItem9;
private System.Windows.Forms.MenuItem menuItem4;
private System.Windows.Forms.MenuItem menuItem3;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label lbl_portfolio;
private System.Windows.Forms.Label lbl_sessgains;
private System.Windows.Forms.Label lbl_sessstart;
private System.Windows.Forms.RichTextBox rt_log;
private System.Windows.Forms.RichTextBox rtf_portfoliotxt;
private System.Windows.Forms.Label lbl_tickerlist;
private System.ComponentModel.Container components = null;

public MainForm()
{

InitializeComponent();
mylog = new writeLog();
mylog.OnlogWrite += new logHandler(updateLogWindow);
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lbl_program_status = new
System.Windows.Forms.Label();
this.mainMenu1 = new System.Windows.Forms.MainMenu
();
this.menuItem1 = new System.Windows.Forms.MenuItem
();
this.menuItem2 = new System.Windows.Forms.MenuItem
();
this.menuItem5 = new System.Windows.Forms.MenuItem
();
this.menuItem3 = new System.Windows.Forms.MenuItem
();
this.menuItem6 = new System.Windows.Forms.MenuItem
();
this.menuItem7 = new System.Windows.Forms.MenuItem
();
this.menuItem8 = new System.Windows.Forms.MenuItem
();
this.menuItem9 = new System.Windows.Forms.MenuItem
();
this.menuItem4 = new System.Windows.Forms.MenuItem
();
this.label1 = new System.Windows.Forms.Label();
this.rtf_portfoliotxt = new
System.Windows.Forms.RichTextBox();
this.lbl_portfolio = new System.Windows.Forms.Label
();
this.lbl_sessgains = new System.Windows.Forms.Label
();
this.lbl_sessstart = new System.Windows.Forms.Label
();
this.rt_log = new System.Windows.Forms.RichTextBox
();
this.lbl_tickerlist = new System.Windows.Forms.Label
();
this.SuspendLayout();
//
// lbl_program_status
//
this.lbl_program_status.Location = new
System.Drawing.Point(24, 408);
this.lbl_program_status.Name = "lbl_program_status";
this.lbl_program_status.Size = new
System.Drawing.Size(576, 16);
this.lbl_program_status.TabIndex = 1;
this.lbl_program_status.Text = "Autofolio Log";
//
// mainMenu1
//
this.mainMenu1.MenuItems.AddRange(new
System.Windows.Forms.MenuItem[] {


this.menuItem1,


this.menuItem5,


this.menuItem8});
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.MenuItems.AddRange(new
System.Windows.Forms.MenuItem[] {


this.menuItem2});
this.menuItem1.Text = "File";
//
// menuItem2
//
this.menuItem2.Index = 0;
this.menuItem2.Text = "Exit";
this.menuItem2.Click += new System.EventHandler
(this.menuItem2_Click);
//
// menuItem5
//
this.menuItem5.Index = 1;
this.menuItem5.MenuItems.AddRange(new
System.Windows.Forms.MenuItem[] {


this.menuItem3,


this.menuItem6,


this.menuItem7});
this.menuItem5.Text = "Trade";
//
// menuItem3
//
this.menuItem3.Index = 0;
this.menuItem3.Text = "Start Newsfeed Scans";
this.menuItem3.Click += new System.EventHandler
(this.menuItem3_Click);
//
// menuItem6
//
this.menuItem6.Index = 1;
this.menuItem6.Text = "Start Trading";
//
// menuItem7
//
this.menuItem7.Index = 2;
this.menuItem7.Text = "Forfeit Positions";
this.menuItem7.Click += new System.EventHandler
(this.menuItem7_Click);
//
// menuItem8
//
this.menuItem8.Index = 2;
this.menuItem8.MenuItems.AddRange(new
System.Windows.Forms.MenuItem[] {


this.menuItem9,


this.menuItem4});
this.menuItem8.Text = "Tools";
//
// menuItem9
//
this.menuItem9.Index = 0;
this.menuItem9.Text = "Options";
//
// menuItem4
//
this.menuItem4.Index = 1;
this.menuItem4.Text = "Set Thresholds";
//
// label1
//
this.label1.Location = new System.Drawing.Point(24,
40);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(168, 16);
this.label1.TabIndex = 3;
this.label1.Text = "Tickers In the News...";
//
// rtf_portfoliotxt
//
this.rtf_portfoliotxt.Location = new
System.Drawing.Point(216, 64);
this.rtf_portfoliotxt.Name = "rtf_portfoliotxt";
this.rtf_portfoliotxt.Size = new System.Drawing.Size
(688, 336);
this.rtf_portfoliotxt.TabIndex = 5;
this.rtf_portfoliotxt.Text = "";
//
// lbl_portfolio
//
this.lbl_portfolio.Location = new
System.Drawing.Point(216, 40);
this.lbl_portfolio.Name = "lbl_portfolio";
this.lbl_portfolio.Size = new System.Drawing.Size
(376, 16);
this.lbl_portfolio.TabIndex = 6;
this.lbl_portfolio.Text = "Current Portfolio";
//
// lbl_sessgains
//
this.lbl_sessgains.Location = new
System.Drawing.Point(920, 64);
this.lbl_sessgains.Name = "lbl_sessgains";
this.lbl_sessgains.Size = new System.Drawing.Size
(96, 23);
this.lbl_sessgains.TabIndex = 7;
this.lbl_sessgains.Text = "Session Gains:";
//
// lbl_sessstart
//
this.lbl_sessstart.Location = new
System.Drawing.Point(928, 80);
this.lbl_sessstart.Name = "lbl_sessstart";
this.lbl_sessstart.Size = new System.Drawing.Size
(88, 16);
this.lbl_sessstart.TabIndex = 8;
this.lbl_sessstart.Text = "Session Start:";
//
// rt_log
//
this.rt_log.Location = new System.Drawing.Point(24,
432);
this.rt_log.Name = "rt_log";
this.rt_log.Size = new System.Drawing.Size(880,
264);
this.rt_log.TabIndex = 9;
this.rt_log.Text = "";
//
// lbl_tickerlist
//
this.lbl_tickerlist.BackColor =
System.Drawing.Color.White;
this.lbl_tickerlist.Location = new
System.Drawing.Point(32, 72);
this.lbl_tickerlist.Name = "lbl_tickerlist";
this.lbl_tickerlist.Size = new System.Drawing.Size
(168, 328);
this.lbl_tickerlist.TabIndex = 10;
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(6,
15);
this.ClientSize = new System.Drawing.Size(1216,
736);
this.Controls.Add(this.lbl_tickerlist);
this.Controls.Add(this.rt_log);
this.Controls.Add(this.lbl_sessstart);
this.Controls.Add(this.lbl_sessgains);
this.Controls.Add(this.lbl_portfolio);
this.Controls.Add(this.rtf_portfoliotxt);
this.Controls.Add(this.label1);
this.Controls.Add(this.lbl_program_status);
this.Menu = this.mainMenu1;
this.Name = "MainForm";
this.Text = "Autofolio 1.0";
this.ResumeLayout(false);

}
#endregion

[STAThread]
static void Main()
{
Application.Run(new MainForm());
}

private void menuItem2_Click(object sender,
System.EventArgs e)
{
Application.Exit();
}

private void menuItem3_Click(object sender,
System.EventArgs e)
{
ArrayList currlist = new ArrayList();
fetch_tickers latestticker = new fetch_tickers
(currlist);
currlist=latestticker.fetch_list();
IEnumerator numerator = currlist.GetEnumerator();
if(currlist.Count!=0)
{
while(numerator.MoveNext())
{

this.lbl_tickerlist.Text=this.lbl_tickerlist.Text+
(numerator.Current.ToString()+Environment.NewLine);

}
}
}

public void updateLogWindow(object thisLog, loggerEventArgs
lea)
{

this.rt_log.Text += "Hello";// Environment.NewLine +
lea.logCaller + " -- " + lea.logData;

}
}
}


Here's my events and associated stuff:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Xml;
using System.Net;
using System.Text;
using System.IO;
using System.Text.RegularExpressions ;
using System.Diagnostics;
using System.Threading;


namespace autofolio
{
public delegate void logHandler(object sender, loggerEventArgs
lea);

public class fetch_tickers
{
private ArrayList currlist=new ArrayList();
private ArrayList newlist=new ArrayList();
private ArrayList urlist=new ArrayList();

public fetch_tickers(ArrayList currentlist)
{
this.currlist=currentlist;
}

public ArrayList fetch_list()
{
string begStr="";
string matchStr="";
string urlstring;
string storystring;
string tickerstring;
string storymatchstring;

WebRequest myRequest = WebRequest.Create
("http://news.moneycentral.msn.com/breaking/breakingnews.asp");

// Return the response.
WebResponse myResponse = myRequest.GetResponse();
begStr=new StreamReader(myResponse.GetResponseStream
(),Encoding.Default).ReadToEnd();

writeLog mylog=new writeLog();
mylog.publish("Fetching latest ticker
list","fetch_tickers");

begStr = begStr.Replace("\n", "");
begStr=begStr.Replace("<font color=ff0020>","");
begStr=begStr.Replace("</font></font>","</font>");

matchStr="href\\s*=\\s*(?:\"(?<webpath>[^\"]*)\"|(?
<webpath>[^\\s>]+)[\\s>])";

new Regex(matchStr, RegexOptions.Compiled);
IEnumerator iEnumerator = Regex.Matches(begStr,
matchStr).GetEnumerator();
while(iEnumerator.MoveNext())
{
Match match=(Match)iEnumerator.Current;
if(iEnumerator.Current.ToString().IndexOf
("breakingnewsarticle")>0)
{

urlstring="http://news.moneycentral.msn.com/breaking/"+
(match.Value.ToString().Substring(6,(match.Value.Length-8)));
//newlist.Add(urlstring);
urlist.Add(urlstring);

}

}//end while

IEnumerator numer2=urlist.GetEnumerator();
while(numer2.MoveNext())
{

WebRequest storytext=WebRequest.Create
(numer2.Current.ToString());
WebResponse
storyresponse=storytext.GetResponse();
storystring= new StreamReader
(storyresponse.GetResponseStream(),Encoding.Default).ReadToEnd();

storystring = storystring.Replace("\n", "");
storystring=storystring.Replace("<font
color=ff0020>","");
storystring=storystring.Replace("</font>
</font>","</font>");

storymatchstring="US:[A-Z.]*";

new Regex
(storymatchstring,RegexOptions.Compiled);
IEnumerator numer3=Regex.Matches
(storystring,storymatchstring).GetEnumerator();
while(numer3.MoveNext())
{

tickerstring=numer3.Current.ToString();
tickerstring=tickerstring.Remove(0,3);
if (!newlist.Contains(tickerstring))
{
newlist.Add(tickerstring);
}
}//end while
}//end while


myResponse.Close();


return this.newlist;
}//end method fetch_lest

}// end class fetch_tickers

public class appTimer
{
public delegate void appTimerHandler(object timer,
timerEventArgs timerArgs);
public event appTimerHandler OnFiveSecondLapse;
private int second=0;

public void start_clock()
{
for(;;)
{
Thread.Sleep(10);
DateTime dt=DateTime.Now;
if (dt.Second == this.second+5)
{
timerEventArgs thisTimer=new
timerEventArgs();
if (OnFiveSecondLapse !=null)
{

OnFiveSecondLapse
(this,thisTimer);
}
}

if (dt.Second == this.second+10)
{

this.second=dt.Second;

}


}


}





}

public class timerEventArgs : EventArgs
{

public timerEventArgs()
{
}


}
public class loggerEventArgs : EventArgs
{
public readonly string logData;
public readonly string logCaller;

public loggerEventArgs (string logString, string caller)
{
this.logCaller=caller;
this.logData=logString;
}


}
public class writeLog
{
private string _logData;
private string _logCaller;

public event logHandler OnlogWrite;

public writeLog()
{
}
public void publish(string logData, string caller)
{
this._logData=logData;
this._logCaller=caller;
//loggerEventArgs thislogevent = new loggerEventArgs
(this._logData,this._logCaller);
if(OnlogWrite != null)
{
OnlogWrite(this,new loggerEventArgs(this.
_logData,this._logCaller));
}
}
}

}//end namespace


But my event doesn't fire. Any clues?
 
G

Guest

Too much code to go through in detail but the one thing that I noticed was that you have the Delegate within th
class, try changing so that it is outside of the class as follows.

public delegate void appTimerHandler(object timer, timerEventArgs timerArgs)

public class appTime
{
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top