从子表单更改父表单中的属性的正确方法是什么?

时间:2009-08-15 23:20:09

标签: c# winforms controls parent-child

我只是想知道我这样做是否正确。我有2个表单父表单和子表单(选项对话框)。要从我的子表单更改父表单中的属性,我使用如下代码:

// 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;
}

我的表单上只有一个RichTextBox。不得不循环遍历1个控件的数组似乎很愚蠢。这是正确的方法还是有更简单的方法?

1 个答案:

答案 0 :(得分:9)

根本不更改父表单中的属性。相反,您的子表单应该引发父表单侦听的事件,并相应地更改其自己的值。

从子进程处理父表单会创建双向耦合 - 父表单拥有子表单,但子表单对父表单也有深入了解和依赖。冒泡是已确立的解决方案,因为它允许信息向上流动('冒泡'),同时避免任何严格的耦合。

以下是事件的最基本示例。它不包括在事件中传递特定信息(这是您可能需要的信息),但涵盖了这一概念。

以您的孩子形式:

//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);
}

以您的父母形式:

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
}

正如我上面所说,您可能需要在活动中传递一些特定信息。我们有几种方法可以做到这一点,但最简单的方法是创建自己的EventArgs类和自己的委托。看起来您需要指定某个值是设置为true还是false,所以让我们使用:

public class BooleanValueChangedEventArgs : EventArgs
{
    public bool NewValue;

    public BooleanValueChangedEventArgs(bool value)
        : base()
    {
        this.NewValue = value;
    }
}

public delegate void HandleBooleanValueChange(object sender, BooleanValueChangedEventArgs e);

我们可以更改我们的活动以使用这些新签名:

public event HandleBooleanValueChange SomethingHappened;

我们传递自定义的EventArgs对象:

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

我们相应地更改了父级中的事件处理:

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;
}