2012-04-12 12 views
5

アイテムのリストを含むユーザーコントロールがあり、currentIndexが変更されたときにイベントを発生させます。また、変更されたときに2つの他のメソッドを呼び出す必要があります。コントロール(画像を変更し、いくつかのボタンをブロック/ブロック解除する)。プロパティの変更後にメソッドを呼び出す場合

私が知りたいことは、既に働いているので、好奇心から外に出ているのは、この2つの方法を呼び出す方が適切なのはいつですか?

CurrentIndexプロパティ内で呼び出す必要がありますか?私はOnCurrentIndexChanged(...)の中でそれらを呼び出すべきですか?クラス内のイベントを処理してそれを行うべきですか?

答えて

6

標準のイベント生成パターンを実装し、OnCurrentIndexChanged protected virtualを作成して、派生クラスがメソッドをオーバーライドしてイベントの生成および/または処理を変更できるようにします。

残念なことに、茶葉を読む必要があります。なぜ誰かがこの方法を無効にしたいですか?そしてもっと真剣に、がメソッドをオーバーライドすると、コントロールが途切れることがありますか?コードをよく知らない人にとっても、あなたにとってはまったく簡単なことではありません。 .NETフレームワークのコードでも同様に適用される原則は、可能な限り行うことです。ただイベントを起こしてください。派生したクラスが何かばかげたことをするときに破損の確率を最小限に抑えますが、base.OnCurrentIndexChangedを呼び出さないように、完全に共通です。

コントロールの動作は、UserControlの実装の詳細です。そのため、CurrentIndexプロパティ設定ツールでプロパティを変更し、OnCurrentIndexChanged()を呼び出します。あなたのクラスから派生した人は、必要に応じてその行動を無効にすることができます。 OnCurrentIndexChanged()メソッドを呼び出すことを忘れても何も問題はありません。しかし、制御変数を保護されたの代わりに保護する必要があることに注意してください。だから彼らはが必要な場合、動作を無効にすることができます。

これはあなたにはあまりにもうっとうしい場合は、まったく仮想メソッドを使用しないことをためらっていません。何十万人ものプログラマがコントロールで対応する必要はありません:)

+0

継承するクラスが実際に私の基底クラスをオーバーライドできるという事実を考えて、アプローチにいくつかの視点を置きます。ありがとうございました。 – PedroC88

2

ユーザーコントロールには、選択した項目を表すプロパティがあります。次に、オブジェクトの設定中にイベントメソッドを呼び出して、ユーザーコントロールを変更します。そうすることで、将来、リスナーを追加する必要がある場合は、setterメソッドで別のハンドラーを追加するだけで済みます。これはMVVMアプリケーションではかなり一般的で、かなり保守性があります。

+0

これは基本的に私が持っているものですが、オブジェクト自身を設定するのではなく、オブジェクトのインデックスを設定し、インデックスの設定者でイベントを発生させます。同じセッター内で他のメソッドを呼び出す必要があるかどうかわかりません。またはイベントに提起する方法の中で?または同じクラス内のデリゲート内にありますか?またはあなたが出てくる他の場所。 – PedroC88

+1

@ PedroC88私は、プロパティの設定者から各メソッドを呼び出します。私はそれが十分に使用されているのを見て、コントロールが複雑になるとメソッドを追加するのは簡単になります。これは、INotifyPropertyChangedインターフェースと抽象化の要点です。 – Josh

+0

これは私が今実際どのようにしているのか、私はプロパティのセッターで両方のメソッドを呼び出すだけで、より良いアプローチがあるかどうか(そしてその理由)を見たいと思っていました。私たちはそこに同意したようだ。 P.S.私は 'INotifyPropertyChanged'を実装していません – PedroC88

1

UserControlはListControlとして機能するため、2つのイベントと2つのプロパティを実装する必要があります。

public event System.EventHandler SelectedIndexChanged; 
public event System.EventHandler SelectionChangeCommitted; 

public int SelectedIndex { 
    get; 
    set; 
} 

public T SelectedItem { // Where T is whatever your type is 
    get; 
    set; 
} 

SelectedIndexChangedは常に、常にあなたの選択したインデックスが変更されたときにトリガする必要があるアクションに使用する必要があります。ユーザが物理的に選択を変更すると、SelectionChangeCommittedのみになります。 2つの間の分離は重要な違いであり、.NETのほとんどのコントロールはこのパターン(たとえばComboBox)に従いますが、イベントに同じ名前を使用することはできません。

これで、プロパティを変更する必要があるコントロールが同じユーザーコントロール内にある場合は、もちろん、適切なイベントのユーザーコントロールコード内でコントロールする必要があります。さもなければ、コードは孤児にされなければなりません。フォームまたは別のユーザーコントロール)に参加し、そこで作業を行うことができます。

順本当にあなたの要件に依存しますが、(それは奇妙な行動を導入するように一度変化当たり以上ではなく)SelectedIndexChanged常にが発生しなければならない、と再びSelectionChangeCommittedはユーザーのみ(例えばによって提起されなければならない。設定SelectedIndexまたはSelectedItem)を使用します。

ユーザが知る前に内部のものが起きた場合、まずSelectedIndexChangedを呼び出してからSelectionChangeCommittedを呼び出す必要があります。それが問題でなければ、または。後で注文を変更すると、コントロールを実装しているユーザーの変更が破棄される可能性があるため、決定が確実であることを確認してください。

2つの違いはSelectedIndexであり、SelectedItemは内部的にリストをクリアしたり、新しいアイテムを追加したりするなどの方法で更新されますが、必ずしも物理的なユーザーアクションであっても、 。

これが役に立ちます。

関連する問題