【问题标题】:What is the correct way to change properties in a parent form from a child form?从子表单更改父表单中的属性的正确方法是什么?
【发布时间】:2009-08-15 23:20:09
【问题描述】:

我只是想知道我这样做是否正确。我有 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 个控件似乎很愚蠢。这是正确的方法还是有更简单的方法?

【问题讨论】:

    标签: c# winforms controls parent-child


    【解决方案1】:

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

    从子窗体操作父窗体创建了一种双向耦合 - 父窗体拥有子窗体,但子窗体也对父窗体有亲密的了解和依赖。冒泡是解决此问题的既定解决方案,因为它允许信息向上流动(“冒泡”),同时避免任何严格的耦合。

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

    在您的子表单中:

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

    【讨论】:

    • 我是 C# 新手,你能给出一个简短的例子或一个链接。 ;-)
    • 感谢您的更新。它真的帮助我理解了你在说什么。
    • 您也可以只使用EventHandler&lt;BooleanValueChangedEventArgs&gt; 而不是创建自己的委托类型。这也在逻辑上将其标记为事件处理程序委托。
    猜你喜欢
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 2019-08-29
    • 2022-01-16
    • 1970-01-01
    相关资源
    最近更新 更多