5

私はこれを正しい方法でやっているのだろうかと思っていました。親フォームと子フォーム(オプションダイアログ)の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 つのコントロールの配列をループする必要があるのはばかげているようです。これは正しい方法ですか、それとももっと簡単な方法はありますか?

4

1 に答える 1

10

親フォームのプロパティを変更することはまったく適切ではありません。代わりに、子フォームは、親フォームがリッスンするイベントを発生させ、それに応じて独自の値を変更する必要があります。

子から親フォームを操作すると、双方向の結合が作成されます。親フォームは子を所有しますが、子も親フォームに関する詳細な知識と依存関係を持っています。バブリングは、厳密な結合を回避しながら情報を上方に流す (「バブリング」) ことができるため、これに対する確立されたソリューションです。

これは、イベンティングの最も基本的な例です。イベントで特定の情報を渡すことは含まれませんが (必要になる場合があります)、概念については説明します。

子フォームで:

//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;
}
于 2009-08-15T23:22:03.027 に答える