On Wed, 28 Nov 2007 01:45:13 -0800, csharpula csharp
<cs*******@yahoo.comwrote:
>How do formB is aware of that event? How do I connect the both forms?
Thank you!
*** Sent via Developersdex http://www.developersdex.com ***
Hi,
1) Derive a class from Eventargs to hold your data.
e.g. Real code snippet, the data is a dictionary
****Event Class Code*********
public class PremiseMapEventArgs:EventArgs
{
private IEnumerable<KeyValuePair<Int32,Premise>pList;
public PremiseMapEventArgs(IEnumerable<KeyValuePair<Int32 ,
Premise>pCol)
{
pList = pCol;
}
public IEnumerable<KeyValuePair<Int32,Premise>PremisesToM ap
{
get { return pList; }
set { pList = value; }
}
}
2) On the form say FormB, that needs to tell the other form whats
happened, create an event.
*****FORMB Event Generator Code*********
public delegate void PremiseMapEventHandler(object sender,
PremiseMapEventArgs e); //Delegate
public event PremiseMapEventHandler MapPremise; // Event declaration
of type previous declared
Generating the event with data destined for FormA
private void MapUnGeocodedPremise_Click(object sender, EventArgs e)
{
IEnumerable<KeyValuePair<Int32,Premise>pCol = new
Dictionary<Int32,Premise>(); // Make the dictionary
foreach (Premise premise in lbUngeocoded.SelectedItems)
{
((Dictionary<Int32,Premise>)pCol).Add(premise.ID,p remise);//Fill the
Dictionary
}
PremiseMapEventArgs m = new PremiseMapEventArgs(pCol); //
Make a new carrier and put in the data.
MapPremise(this, m);// Raise the event. Handled by formA
}
3) On the form that needs to know what's happening (FormA) consume
the event.
In this case I am creating FormB from FormA. The event thing can
work either or both ways.
*****FORMA Consumer Code follows*******
private void geocodeToolStripMenuItem_Click(object sender, EventArgs
e)//User wants to create FormB
{
ThreadStart ts = RunGeocode;
Thread t = new Thread(ts);
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
private void RunGeocode()// makeFormB
{
frmGeoCode f;
IEnumerable<RouteRouteList;
if(!lRouteSelected)
{
f = new frmGeoCode(); // make a plain second form
}
else
{
RouteList = new List<Route>();
foreach (Route r in lbRoutes.SelectedItems)
{
((List<Route>)RouteList).Add(r);
}
f= new frmGeoCode(RouteList); make a new second form
with preloaded data
}
f.myForm = this;// ***Allows FormB to consume events reaised
f.MapPremise += new frmGeoCode.PremiseMapEventHandler(f_MapPremise);
//*****DECLARING EVENT HANDLER FOR CONSUMING EVENT FROM FORMB using
method 'f_MapPremise' ********
Application.Run(f);// Run FormB
}
Make use of the incoming data in event from FormB .
void f_MapPremise(object sender, PremiseMapEventArgs e)
{
CurrentPremises = e.PremisesToMap; // get the dictionary
out of the carrier
PlacePremise(CurrentPremises); // Make use of the
dictionary
}
Last point is that because event handlers are on a different thread to
the GUI you will need to invoke any methods that update the GUI .
private void PlacePremise(IEnumerable<KeyValuePair<Int32,Premis e>p)
{
if (this.lbPlacingPremises.InvokeRequired) //Want to
update a listbox
{
dUpDatePlacingString d = UpdatelbPlacingPremises; //
**********delegate with correct signature declared elsewhere
i.e. private delegate void
dUpDatePlacingString(IEnumerable<KeyValuePair<Int3 2,Premise>p);
***********
this.lbPlacingPremises.Invoke(d, new object[] { p
});//Listbox invokes the delegate
}
else
UpdatelbPlacingPremises(p);// Don't ever get here but
heh.
}
private void
UpdatelbPlacingPremises(IEnumerable<KeyValuePair<I nt32,Premise>p)
{
foreach (Premise premise in
((Dictionary<Int32,Premise>)p).Values)
{
lbPlacingPremises.Items.Add(premise) ;
}
}
Obviously the data can be anything,it just happened to be a dictionary
in some code I was working on recently.
This whole approach is covered in the MSDN library search for 'custom
events and delegates'
hth
Bob