Calling Event Issues??? Help!  
Author Message
Tryin2Bgood





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

When my form closes I want to fire an event that will do somethings....but i think i may be calling it wrong...Here is my method signiture...and this is the error....

[code languge="C#"]

public delegate void frmClosing(object sender, FormClosingEventArgs e);

public frmClosing ClosingVendorDetails;

public static void DisplayVendorDetails(System.Windows.Forms.Form ParentForm, BHFreight.Tracking.BusinessObjects.VendorOrderLegDetail _VendorLeg, frmClosing ClosingForm)

{

BHFreight.Tracking.UI.MainWindows.VendorOrderLegDetailsForm frmVendorLeg = new VendorOrderLegDetailsForm();

frmVendorLeg._VendorDetail = _VendorLeg;

frmVendorLeg.LoadVendorObjectToForm();

frmVendorLeg.ShowDialog(ParentForm);

frmVendorLeg.FormClosing += ClosingForm;

}

[/code]

then i want my delegate to call this method in another class..

[code language="C#"

public delegate void VendorDetailsClosing(object sender, FormClosingEventArgs e);

public VendorDetailsClosing OnVendorDetailsClosing;

Tracking.UI.MainWindows.VendorOrderLegDetailsForm.frmClosing CloseVendorDetail = new Tracking.UI.MainWindows.VendorOrderLegDetailsForm.frmClosing(LoadVendorControl);

Tracking.UI.MainWindows.VendorOrderLegDetailsForm.DisplayVendorDetails(this.FindForm(), (BHFreight.Tracking.BusinessObjects.VendorOrderLegDetail)_OrderLegDetail, CloseVendorDetail);

[/code]

Is this the right way to do this




Visual C#10  
 
 
TaylorMichaelL





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

Here's the pseudo code for the static method:

Create an instance of a form
Show the form as modal (it blocks until the form closes)
Hook up an event handler to the form

As a result your event handler is hooked up but will never be called as the form is closed before you hook it up. However looking at your calling code it doesn't really make sense why you would do that anyway. You might have had several different scenarios in mind so I'll try and cover both.

In the first scenario you want the form to remain open after you've created it. In this case call Show rather than ShowDialog. The form will remain open until the user closes it. To be safe move the EH assignment call to just before Show. Now the EH will be called when the form closes. Of course you don't know when that is.

public static void DisplayVendorDetails(System.Windows.Forms.Form ParentForm, BHFreight.Tracking.BusinessObjects.VendorOrderLegDetail _VendorLeg, frmClosing ClosingForm)
{
BHFreight.Tracking.UI.MainWindows.
VendorOrderLegDetailsForm frmVendorLeg = new VendorOrderLegDetailsForm();
frmVendorLeg._VendorDetail = _VendorLeg;
frmVendorLeg.LoadVendorObjectToForm();
frmVendorLeg.FormClosing += ClosingForm;
frmVendorLeg.Show(ParentForm);
}

In the second scenario the form should be modal. In this case hooking into the close method is not useful since control returns from DisplayVendorDetails only after the form is closed. Therefore after this call you can do any post-close clean up.

public static void DisplayVendorDetails(System.Windows.Forms.Form ParentForm, BHFreight.Tracking.BusinessObjects.VendorOrderLegDetail _VendorLeg, frmClosing ClosingForm)
{
BHFreight.Tracking.UI.MainWindows.
VendorOrderLegDetailsForm frmVendorLeg = new VendorOrderLegDetailsForm();
frmVendorLeg._VendorDetail = _VendorLeg;
frmVendorLeg.LoadVendorObjectToForm();
frmVendorLeg.ShowDialog(ParentForm);
ClosingForm();
}

Tracking.UI.MainWindows.VendorOrderLegDetailsForm.DisplayVendorDetails(this, (BHFreight.Tracking.BusinessObjects.VendorOrderLegDetail)_OrderLegDetail, CloseVendorDetail);

As a final note you don't need to call this.FindForm in the second function because the this value gives you the same result if you are within the form class itself.

Michael Taylor - 11/28/06


 
 
Tryin2Bgood





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

i switched it up a bit.....and its working kinda...but its not changing my labels to blanks though....I have a user controls that i click a button on and it shows a form....then when that form is closing it calls its formclosing event....


private void VendorOrderLegDetailsForm_FormClosing(object sender, FormClosingEventArgs e)
{
frmClosing _CloseDetails = new frmClosing(_OrderLegData.LoadVendorControl);
_CloseDetails(sender, e);
}


then it calls this method......

[code languge="C#"]

public void LoadVendorControl(object o, FormClosingEventArgs e)

{

lblName.Text = "";

lblBeginCity.Text = "";

lblPickUpDate.Text = "";

lblTimeStartingPoint.Text = "";

lblSetBy.Text = "";

lblEndingTime.Text = "";

lblTelephone.Text = "";

lblBeginState.Text = "";

lblEndingState.Text = "";

lblEndingCity.Text = "";

}

[/code]

But the labels do not turn blank that have the default values still there.....any idea on why these values are not getting changed



 
 
TaylorMichaelL





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

I think you're confusing calling an event with setting one up but I'm not completely sure. You didn't mention whether the form was modal or not. If it is modal then you don't need to deal with event handlers. Just do whatever you need to do after the ShowDialog method returns. If it is modeless then hook up the EH as I talked about earlier.

Now the event will be raised and your LoadVendorControl method will be called. I'm not sure what the VendorOrderLegDetailsForm_FormClosing
method you provided is doing. If this doesn't answer your question then please post the new code that you wrote including the method to create the form and hook up the event handler and the code that calls the method. We'll then try to help you out some more.

Michael Taylor - 11/28/06


 
 
Tryin2Bgood





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

This is how my form gets called

.Tracking.UI.MainWindows.VendorOrderLegDetailsForm.DisplayVendorDetails(this.FindForm(), (.Tracking.BusinessObjects.VendorOrderLegDetail)_OrderLegDetail);

this is the actualy method...


public static void DisplayVendorDetails(System.Windows.Forms.Form ParentForm, BHFreight.Tracking.BusinessObjects.VendorOrderLegDetail _VendorLeg)
{
BHFreight.Tracking.UI.MainWindows.
VendorOrderLegDetailsForm frmVendorLeg = new VendorOrderLegDetailsForm();
frmVendorLeg._VendorDetail = _VendorLeg;
frmVendorLeg.LoadVendorObjectToForm();
frmVendorLeg.ShowDialog(ParentForm);

}


And here is the the form's event for Closing in which i call my delegate...

private void VendorOrderLegDetailsForm_FormClosing(object sender, FormClosingEventArgs e)

{

frmClosing _CloseDetails = new frmClosing(_OrderLegData.LoadVendorControl);

_CloseDetails(sender, e);

}



 
 
Tryin2Bgood





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

When i call this method and I stepping through the code and i do o in my Immediate Window.....o has all the values i need in it but how do i get those values from o, so i can assign them to the apropiate control

[code languge="C#"]

public void LoadVendorControl(object o, FormClosingEventArgs e)

{

lblName.Text = "";

lblBeginCity.Text = "";

lblPickUpDate.Text = "";

lblTimeStartingPoint.Text = "";

lblSetBy.Text = "";

lblEndingTime.Text = "";

lblTelephone.Text = "";

lblBeginState.Text = "";

lblEndingState.Text = "";

lblEndingCity.Text = "";

}

[/code]



 
 
TaylorMichaelL





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

Ok. I think you're overcomplicating event handling and it is causing you some problems. I recommend that you simplify your code as follows:

Remove the frmClosing delegate and convert any references to the standard FormClosingEventHandler. You should actually probably switch to FormClosedEventHandler unless you want to be able to cancel the close request.

Modify your static method as follows:

public static void DisplayVendorDetails(System.Windows.Forms.Form ParentForm, BHFreight.Tracking.BusinessObjects.VendorOrderLegDetail _VendorLeg)
{
BHFreight.Tracking.UI.MainWindows.VendorOrderLegDetailsForm frmVendorLeg = new VendorOrderLegDetailsForm();
frmVendorLeg._VendorDetail = _VendorLeg;
frmVendorLeg.LoadVendorObjectToForm();
bool bCancelled = frmVendorLeg.ShowDialog(ParentForm) != DialogResults.Ok;

//Call the method that would normally be invoked when the form closes (since the form is now closed)
FormClosedEventHandler hdlr = _OrderLegData.LoadVendorControl; //I'm not sure where you got this value but it could just be a parameter)
if (hdlr != null)
hdlr(frmVendorLeg, new FormClosingEventArgs(CloseReason.UserClosing, bCanceled));
}

Remove the VendorOrderLegDetailsForm_FormClosing method completely.

That should solve your problem. To give you the complete answer however I'll now show you how to handle the event in a normal situation (in case you have this requirement later). In this example I use a static method to create a new form, pass the handler to invoke and then modelessly display the form.

public static void DisplayModelessForm ( FormClosedEventHandler closeHandler )
{
//Create the child form
ChildForm childForm = new ChildForm();

//Hook up the handler
if (closeHandler != null)
childForm.FormClosed += closeHandler;

//Show the form modeless
childForm.Show();

}

The method closeHandler will be automatically called when needed. Note that I don't have to override any methods in the child form class nor do I have to define any event handlers. The child form could look like this and it'll work as you expect.

public class ChildForm : Form { }

As a final note in your example code you defined an event handler for your child form like so:

private void VendorOrderLegDetailsForm_FormClosing(object sender, FormClosingEventArgs e)
{
frmClosing _CloseDetails = new frmClosing(_OrderLegData.LoadVendorControl);
_CloseDetails(sender, e);
}

I assume that either through the designer or manually you generated this code:

VendorOrderLegDetailsForm1.FormClosing += VendorOrderLegDetailsForm_FormClosing.

If VendorOrderLegDetailsForm_FormClosing is a method inside the VendorOrderLegDetailsForm class then you should not use event handlers to override the behavior. This is a waste of CPU time. Instead each event that could be raised has a corresponding virtual method that raises it. You should override the virtual method instead. Again this only applies to the specific case where you want to handle an event raised in a form from the form itself. Note that this practice is standard across all of .NET and not just forms. Thus if you wanted to do some additional processing whenever your form was closed you can override the virtual method like so:

public class ChildForm : Form
{
protected override void OnFormClosed ( FormClosedEventArgs e )
{
//Call the base implementation so the event is raised to interested parties
base.OnFormClosed(e);

//Do any custom processing
}
}

Hope this helps,
Michael Taylor - 11/29/06


 
 
Tryin2Bgood





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

Thanks for the help but it left me in the same position I was in before.....and that is the method that gets called does not change the values......

FormClosingEventHandler handle = _OrderLegData.LoadVendorControl;

this line calls this method

public void LoadVendorControl(object o, FormClosingEventArgs e)

{

try

{

lblName.Text = "";

lblBeginCity.Text = "";

lblPickUpDate.Text = "";

lblTimeStartingPoint.Text = "";

lblSetBy.Text = "";

lblEndingTime.Text = "";

lblTelephone.Text = "";

lblBeginState.Text = "";

lblEndingState.Text = "";

lblEndingCity.Text = "";

}

catch (Exception ex)

{

MessageBox.Show(ex.ToString());

}

}

but my labels to do not return blanks, or I still do not know how to get the data from the object sending it......Shouldnt I be able to access that data somehow...When i am debugging and stepping through the code I see the values but how do i access the values within that object



 
 
TaylorMichaelL





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

The form that raised the event is available in the sender parameter. You'll need to cast it to get access to the form. Once you do that you have access to the values you need.

private void LoadVendorControl(object sender, FormClosingEventArgs e )
{
Form frm = sender as Form;
lblName.Text = frm.SomeField;
...
}

Michael Taylor - 11/29/06


 
 
Tryin2Bgood





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

Well what i had to do is make all my controls public in the form i needed but my values did not change i dont know why though....your help has been great though thanks! but one last thing....What i am doing is I click a button and a control is loaded on that control there is another button that i click which brings up my VendorDetails Screen....Once I set some info in that form i close the form which calls the method _OrderLegData.LoadVendorControl, but for some reason my values on the control dont change.....I think it may have something to do with the control already being loaded or something i dont know.....u got any ideas.....

 
 
TaylorMichaelL





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

Yes, in order to access the controls of a form outside the form they would have to be public. This isn't a good design though as it tightly couples the UI with the data. As for the control creation you can set the properties to whatever value you want and the underlying control will automatically update without any additional work.

You might do better to modify your design to break the UI from the data. To do this create (or use) a business class that contains the data you care about (I'll call it Vendor). In your VendorDetailsForm expose a property of type Vendor. Whenever this property is set refresh the controls in VendorDetailsForm. When the form closes (in the OnOK handler or whatever you use to positively confirm the closure) flush the control values back to the property. On the caller side (the form that was the parent of VendorDetailsForm) update the UI based on the changes made in the form. This is pretty elegant and breaks the coupling you have. Even better is you don't have to expose control properties.

public class Vendor
{
public string Name { }
public string Address { }
...
}

public class MainForm : Form
{
private Vendor m_Vendor;

private void UpdateVendorDetails ( Vendor vendor )
{
lblVendorName.Text = vendor.Name;
lblVendorAddress.Text = vendor.Address;
...
}

private void ShowVendorDetailsButton_OnClick ( object sender, EventArgs e )
{
VendorDetailsForm frm = new VendorDetailsForm();
frm.Vendor = m_Vendor;
if (frm.ShowDialog(this) == DialogResult.OK)
UpdateVendorDetails(m_Vendor);
}
}

public class VendorDetailsForm : Form
{
private Vendor m_Vendor;
public Vendor Vendor
{
get { return m_Vendor; }
set
{
m_Vendor = value;
LoadVendor();
}
}

private void LoadVendor ( )
{
txtName.Text = m_Vendor.Name;
txtAddress.Text = m_Vendor.Address;
...
}

private void SaveVendor ( )
{
m_Vendor.Name = txtName.Text;
m_Vendor.Address = txtAddress.Text;
...
}

protected override void btnOK_OnClicked ( object sender, EventArgs e )
{
SaveVendor();
}

}

Michael Taylor - 11/29/06


 
 
Tryin2Bgood





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

Whats happening is my DisplayVendorDetails is called twice once to instantiate the form the first time then its called again after the formevent has been fired...its called again and sets all my values back to the defaults

 
 
TaylorMichaelL





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

The method should not be called when the form is closed. You should remove any calls to this method during form closing. This will eliminate the reset that you are seeing. Instead only the appropriate method needed to flush the values back to your parent form should be called.

Michael Taylor - 11/29/06


 
 
Tryin2Bgood





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

Thanks for the help....but its wierd....When i am debugging it calls that method again but if i set a breakpoint for that method is breaks when the form is instantiated but when i am closing the method is not called but it still resets the values.....but when i am stepping through the code it goes to that method and the next line after that is when i call the System.Diagnostics.WriteLine(lblName.Text)...the output window shows the default value again.....so some how its getting reset back to the original

 
 
Tryin2Bgood





PostPosted: Visual C# Language, Calling Event Issues??? Help! Top

thanks 4 your help but i ending up getting it to work how i orignally planned here is what i did

first method


public delegate void frmClosing(object o, FormClosingEventArgs e);
private frmClosing _FormClosingMethod;

public static void DisplayVendorDetails(BHFreight.Tracking.BusinessObjects.VendorOrderLegDetail _VendorLeg, frmClosing FormClosingMethod)
{
Tracking.UI.Controls.
OrderLegData _OrderLegData = new Tracking.UI.Controls.OrderLegData();
Tracking.UI.MainWindows.
VendorOrderLegDetailsForm frmVendorLeg = new VendorOrderLegDetailsForm();
frmVendorLeg._VendorDetail = _VendorLeg;
frmVendorLeg.LoadVendorObjectToForm();
frmVendorLeg._FormClosingMethod = FormClosingMethod;
frmVendorLeg.ShowDialog();
}

calling method


private void bnOK_Click(object sender, System.EventArgs e)
{
try

{
LoadFormToVendorObject();
this._FormClosingMethod(this,null);
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}

Method to point too


Tracking.UI.MainWindows.VendorOrderLegDetailsForm.frmClosing _FormClosing = new Tracking.UI.MainWindows.VendorOrderLegDetailsForm.frmClosing(LoadVendorControl);

public void LoadVendorControl(object o, FormClosingEventArgs e)
{
try

{
BHFreight.Tracking.UI.MainWindows.
VendorOrderLegDetailsForm frmVendorDetails = o as BHFreight.Tracking.UI.MainWindows.VendorOrderLegDetailsForm;

lblName.Text = frmVendorDetails.lblVendorCompanyName.Text;
lblBeginCity.Text =
"";
lblPickUpDate.Text =
"";
lblTimeStartingPoint.Text =
"";
lblSetBy.Text =
"";
lblEndingTime.Text =
"";
lblTelephone.Text =
"";
lblBeginState.Text =
"";
lblEndState.Text =
"";
lblEndCity.Text =
"";
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}


#endregion