2011-03-28 8 views
1

私のフォームは3ペインの電子メールクライアントのように見えます。左側は人のリストを含むグリッドです。右上は現在の人物の詳細レコードです。右下の専門知識の現在の人の領域を表示する多くのチェックボックスでカスタムコントロールです:[x]は、調理コントロールが初期化されるのを待つ

[x]のウィンドウのクリーニングが[x]は、脳の手術

[x]はマッサージ療法[X]歌詞のランダムな行為

フォームを開くと、フォームの左側のグリッドにリストされている最初の人にフォーカスが移動し、グリッドのfocused_row_changedイベントが発生します。このイベントのハンドラでは、現在の人物のIDを取得し、その人物の詳細データをデータベースから取り出して詳細レコードを取り込み、その人物の専門分野の行を取り出してチェックボックスを設定します。フォームが最初に開かれたとき以外は、多くのチェックボックスを持つカスタムコントロールがまだ初期化されていないため、これはすべて正常に動作しています。その時点で、MyCustomControlはnullです。

if (null != MyCustomControl) 
{ 
    MyCustomControl.SetCheckedValues(datasource); 
} 

この状況を処理するためのベストプラクティスデザインパターンは何ですか?私のコントロールがまだ完全に初期化されていないとき、私はここで何をしますか?

if (null != MyCustomControl) 
{ 
    MyCustomControl.SetCheckedValues(datasource); 
} 
else 
{ 
    // ?? Wait around for a bit and keep trying every 100ms? 
} 
+0

:あなたのコントロールで

、あなたのような何かを置く:インターフェイスを実装するコントロールのための

public class MyCustomControl: ISupportInitialize { private bool _initializing = false; private void BeginInit() { _initializing = true; } private void EndInit() { _initializing = false; } private void SomeMethodThatWouldRaiseAnEventDuringInit() { if (_initializing) return; //... } } 

Windowsフォームデザイナのチェックをし、.Designer.csファイルにこのコードを生成しますMyCustomControlが初期化される時期と、その初期設定が依存する項目についてもう少し詳しく説明します。 – Yetti

答えて

0

は、他のすべてのUI要素が初期化された後まで呼び出されないサブルーチンであなたのUIの初期化機能を実行し、または代わりに、UIのバックエンドの値にあなたの計算の基礎としています。コメントや他の記事を受けて


あなたが動作するように何かを得ることができない場合、あなたは私が理解からUI

+0

リストを含むグリッドは、フォーカスが行から行に移動するたびに、フォーカスされた行変更イベントを発生させます。これは、ユーザが対話するUIであり、ユーザが異なる人物を選択するたびに人物詳細レコードおよび人物専門知識レコードを取得する必要があります。グリッドの初期化が完了したら、私はコントロールできません。 – Tim

+0

私はリフレッシュボタンを避けることを望んでいます。なぜなら、ユーザーはデータをリフレッシュする必要があることを知り、行動を起こす必要があるからです。理想的には、私は遅いコントロールが目覚めた後にのみ、速いコントロールが目を覚ますようにする方法を見つけたいと思います。私は初期の鳥のコントロールをベッドにとどめて、眠そうなコントロールが目を覚まして「ライズと輝き」と言いたいと思っています。初期の鳥のコントロールに。私は、sleepyheadのコントロールがsleepyheadのInitializationCompleteイベントのフォームのコントロールリストにearlybirdコントロールを追加できると思います。 – Tim

+0

re:私のコントロールがまだ完全に初期化されていないとき、私はここで何をしますか?完全に初期化されるまで待ってからリフレッシュする必要があります。あなたの遅いコントロールが完了したらあなたの速いコントロールに通知できますか? – Beth

0

に「リフレッシュ」ボタンを追加することができ、あなたはMyCustomControl.SetCheckedValues(datasource);を設定しますfocused_row_changedイベントが発生したとき。

これはまた、フォームがロードされているときに発生する傾向があります。たとえば、選択されたインデックスが-1のときにロードするようなイベントが発生するためです。

私がこれを回避する方法は、doneLoadingという形式のグローバルブール値を持つことです。 falseから始まり、Form_Shown()イベントが呼び出されるとtrueになります。

ここからは、実行が許可される前にフォームが実際にロードされるまで待つ必要のあるコードの部分に、if(doneLoading)を置くだけです。あなたのケースでは、私はどうなる:

if(doneLoading) 
{ 
MyCustomControl.SetCheckedValues(datasource); 
} 
+0

Form_Shown()イベントで、Personsグリッドのフォーカスを最初の行に手動で設定する必要があります。しかし、焦点はすでに最初の行にあるので、焦点を当てた行変更イベントは発生しません。だから私は人の詳細レコードと人物の専門知識レコードを取り出すルーチンを手作業で起動しなければならなくて、それを知る前にイベント駆動プログラムではなく、イベント駆動のコーディングと良い旧式の構造化コーディング。それは避けようとしているのですが、それを避けることはできません。 – Tim

+0

@Tim - 私はこの問題またはおそらく望ましい動作を理解していません。最初にフォームが開いたら、MyCustomControlを入力するか、ユーザーが意図的に人を選択するまで待つかどうかを指定しますか?後者の場合は、それが私の答えが促進するものです。私の答えのコードは、フォームのロードが完了するまでSetCheckedValues()メソッドを呼び出さないようにしています。別の言い方をすれば、あなたが以前に持っていたどんなイベントでも、私がそこに置いたコードを置くだけで、フォームが完全に読み込まれる前の全体的な振る舞いを変えるべきです。 – Yetti

+0

フォームがロードされると、コントローラのリストに人名とIDが設定され、Focused_Row_Changedイベントを発生させる最初の行にフォーカスが自動的に設定されます。そのイベントのハンドラでは、フォーカスされた人のIDを取得し、データベースから詳細データを取得します。しかし、フォーム上の別のコントロールはまだそのデータを受け取る準備ができていません。私のコントローラのリストは、そこからデータを受け取るコントロールよりも早く初期化されます。現在のところ、私のハンドラはドアに答えるまでスローポークコントロールのドアをノックしているので、「Mr.コントロールのデータ配信! – Tim

1

彼らはこの問題はISupportInitializeを実装することであったとき、私は私のコントロールでこれを解決した方法を。次のことができ

((System.ComponentModel.ISupportInitialize)(this.customControl1)).BeginInit(); 
/// 
/// customControl1 
/// 
this.customControl1.SelectedIndex = 0; //this would normally raise the event 
((System.ComponentModel.ISupportInitialize)(this.customControl1)).EndInit(); 
+0

これはクイックコントロールまたはスローポークコントロールに入りますか?どのように動作するのか分かりません。スローポークコントロールは、送信されるデータを表示するだけですが、データベースからデータを取得するコントロールは、データを表示するコントロールよりも早く初期化され、読み込まれます。スローポークコントロールの初期化が完了するまで、より速いコントロールの初期化を遅らせる方法はありますか? – Tim

関連する問題