What is the correct way to change properties in a parent form from a child form?

I'm just wondering if I'm doing it right. I have 2 forms of the parent form and a child form (options dialog). To change a property in my parent form from my child form, I use this code:

// Create an array of all rich textboxes on the parent form. var controls = this.Owner.Controls.OfType<RichTextBox>(); foreach (var item in controls) { if (chkDetectUrls.Checked) ((RichTextBox)item).DetectUrls = true; else ((RichTextBox)item).DetectUrls = false; } 

I have only one RichTextBox in my form. It seems silly to iterate over an array of 1 control. Is this the right way to do this, or is there an easier way?

+4
source share
1 answer

It is not possible to change the properties in the parent form at all. Instead, your child form should raise the event that the parent form is listening on and change its own value accordingly.

Manipulating the parent form from the child creates a two-way relationship - the parent form owns the child, but the child also has close knowledge and dependence on the parent form. Bubbling is an established solution for this, as it allows information to flow upward (a β€œbubble”), while avoiding any strict connection.

Here is the simplest example of eventing. It does not include the transmission of certain information in the event (which you may need), but it covers the concept.

In your child form:

 //the event public event EventHandler SomethingHappened; protected virtual void OnSomethingHappened(EventArgs e) { //make sure we have someone subscribed to our event before we try to raise it if(this.SomethingHappened != null) { this.SomethingHappened(this, e); } } private void SomeMethod() { //call our method when we want to raise the event OnSomethingHappened(EventArgs.Empty); } 

And in your parent form:

 void OnInit(EventArgs e) { //attach a handler to the event myChildControl.SomethingHappened += new EventHandler(HandleSomethingHappened); } //gets called when the control raises its event private void HandleSomethingHappened(object sender, EventArgs e) { //set the properties here } 

As I said above, you probably need to pass certain information to your event. There are several ways to do this, but the easiest is to create your own EventArgs class and your own delegate. It looks like you need to indicate if any value is set to true or false, so use this:

 public class BooleanValueChangedEventArgs : EventArgs { public bool NewValue; public BooleanValueChangedEventArgs(bool value) : base() { this.NewValue = value; } } public delegate void HandleBooleanValueChange(object sender, BooleanValueChangedEventArgs e); 

We can change our event to use these new signatures:

 public event HandleBooleanValueChange SomethingHappened; 

And we pass our custom EventArgs object:

 bool checked = //get value OnSomethingHappened(new BooleanValueChangedEventArgs(checked)); 

And we accordingly change the event handling in the parent device:

 void OnInit(EventArgs e) { //attach a handler to the event myChildControl.SomethingHappened += new HandleBooleanValueChange(HandleSomethingHappened); } //gets called when the control raises its event private void HandleSomethingHappened(object sender, BooleanValueChangedEventArgs e) { //set the properties here bool value = e.NewValue; } 
+9
source

All Articles