Shamil Salakhetdinov
shamil at smsconsulting.spb.ru
Mon Jan 25 11:34:09 CST 2010
Hi John -- Here is one of myriads possible solutions how to handle events in caller classes - for form's(/their controls') code behind it will be similar with an exception that you might have to use .Invoke while processing events in event sinks as the latter could run in a different thread than your form's main thread: using System; namespace ConsoleApplication { public class SpRunner { public class SpRunnerStatusReportEventArgs:EventArgs { public int CurrentCount {get; set;} public int MaxCount {get;set; } } public EventHandler<SpRunnerStatusReportEventArgs> StatusReport; public void Run() { const int MAX_COUNT = 5; for (int i = 1; i <= MAX_COUNT; i++) { if (StatusReport != null) { SpRunnerStatusReportEventArgs e = new SpRunnerStatusReportEventArgs(); e.CurrentCount = i; e.MaxCount = MAX_COUNT; StatusReport(this, e); } } } } class Program { static void Main(string[] args) { SpRunner runner = new SpRunner(); runner.StatusReport += new EventHandler<SpRunner.SpRunnerStatusReportEventArgs>(statusReport); runner.Run(); } private static void statusReport(object sender, SpRunner.SpRunnerStatusReportEventArgs e) { System.Console.WriteLine("{0}: Processing {1} of {2}...", sender.GetType(), e.CurrentCount, e.MaxCount); } } } Thank you. -- Shamil -----Original Message----- From: dba-vb-bounces at databaseadvisors.com [mailto:dba-vb-bounces at databaseadvisors.com] On Behalf Of jwcolby Sent: Monday, January 25, 2010 7:50 PM To: VBA Subject: [dba-VB] C#: Raising events Silly me, I thought that events would be easy in C#. I guess once you figure them out they probably are, but coming from VBA where all the behind the scenes stuff is done for you, it is kinda confusing. What I want to do is execute stored procedures, and publish status information about each SP executed on my form starts a process running. I have a class which encapsulates my stored procedure stuff for creating the command object, capturing the parameters and eventually executing the stored procedure. I assume that this object might raise an event when the stored procedure returns i.e. sCmd.ExecuteNonQuery() returns control to C# ? OTOH, I have other classes which USE the SP class. These are the classes that actually call specific stored procedures, pass parameters, and control the program flow depending on whether the called SP succeeds or fails etc. THESE classes should raise an event, sunk on the form, which passes up the SP class instance just executed, IOW I just executed a "Create index" stored procedure and want to display on the form the name of the sp and whether it completed satisfactorily, how long it took and so forth. I am going to go with the classes which execute sequences of SPs being the class that raises the event. I am looking at this as an example: http://www.codeproject.com/KB/cs/csevents01.aspx clsStoredProc creates the command object, packages the parameters, and executes the stored procedure. clsAZExport uses a sequence of stored procedures to perform an export process. So... I create an event delegate definition which defines the event I will raise. Where do I place this? For the moment I have placed it inside of the container where clsStoredProc is defined. I now have to create evargStoredProcedure - a public class for the argument that this event will pass up to the form. The argument is going to be the current instance of the clsStoredProc. Where is this class created? Do I just define a new class at the project level for this event argument. It seems that it is part and parcel of using clsStoredProcedure (which is in its own project) so placing it in the code container for that class seems appropriate. For the moment I have placed it inside of the container where clsStoredProc is defined. Now, in every method of clsAZExport I add two lines: evargStoredProcedure svargSP = new evargStoredProcedure(sp); evStoredProc(this, svargSP); This apparently creates the arguments object and then raises the event. Man oh man, is this a PITA (after VBA). I haven't even begun to sink the event yet. So... back in the form which uses clsAZExport to export data from SQL Server... At this point their example breaks down entirely. I am not writing to the debug window, I am trying to write to a control on a form. While the debug window can be written to from anywhere, a control on a specific form is decidedly specific. Thus the form has to somehow sink the evStoredProc. And I grind to a halt, unable to figure out what to do next. It seems that my clsAZExport declared in the form has an event evStoredProc, and that I need to wire that. I kind of figured that once I did all this I would click on any object that raises an event and I would see a list of their events, but I do not, or I do not know how to see them. As an example if I have a text box, it has events. If I click on that I can see its events, select one and voila, a place to say what to do. How do I do that for an event raised by my class dimensioned and used in my form? If anyone is following this and knows what I am trying to do and what to do next, please speak up. -- John W. Colby www.ColbyConsulting.com