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

发布于 2024-08-02 04:16:21 字数 466 浏览 9 评论 0原文

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

// 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 个控件的数组似乎很愚蠢。这是正确的方法还是有更简单的方法?

I was just wondering if I'm doing this the correct way. I have 2 forms a parent form and a child form (options dialog). To change a property in my parent form from my child form I use code like this:

// 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 only have one RichTextBox on my form. It seems silly to have to loop through a array of 1 control. Is this the correct way to do it or is there an easier way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猥琐帝 2024-08-09 04:16:21

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

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

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

在您的子表单中:

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

It's not appropriate to change properties in a parent form at all. Instead, your child form should raise an event which the parent form listens for, and changes its own value accordingly.

Manipulating the parent form from the child creates a two-way coupling - the parent form owns the child, but the child also has intimate knowledge and dependency on the parent form. Bubbling is the established solution to this, as it allows information to flow upwards ('bubbling') while avoiding any strict coupling.

Here is the most basic example of eventing. It does not include passing specific information in the event (which is what you may need) but 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 some specific information in your event. There's a few ways we can do this, but the simplest one is to create your own EventArgs class and your own delegate. It looks like you need to specify whether some value is set to true or false, so let's use that:

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 change our event handling in the parent accordingly:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文