0

スタイルを持つComboBoxWinForms アプリケーションを持っていDropDownます。つまり、ユーザーが値を入力したり、ドロップダウン リストから選択したりできます。次のようになります。

ここに画像の説明を入力

私の目標は、インデックスに基づいてドロップダウン リストから項目を選択することです。だから私はこれを行います:

//I know for sure that i >= 0 && i < comboBox.Items.Count
comboBox.SelectedIndex = i;  //i = index of the existing item

上記の行の後でメッセージを表示しない限り、これは問題なく機能します。

MessageBox.Show("Error");

この場合、コンボ ボックス内の項目は、このコンピューターでのテスト中に約 80% の時間で選択されました。したがって、ここには明らかにタイミングの問題があります。

私が知る必要があるのは、ComboBox アイテムを選択する「確実な」方法は何ですか? (つまり、次のコード行が実行されたときに選択されていることを確認するか、それを実行しますsynchronously。)

PS。プロパティにテキストを割り当てるだけでよいことはわかっていTextますが、それは私が求めていることではありません。ComboBox の実装でわかるように、カスタム オブジェクトを各項目に割り当てることができます。また、SelectedIndexChanged.

PS2。DropDownこれがスタイルのあるコンボ ボックスのみに影響するのか、それともすべてのコンボ ボックスに影響するのかはわかりません。

4

3 に答える 3

1

メッセージ ボックスComboBoxは、選択したインデックスを更新する処理を中断します。やメッセージ ボックスなどのフォームやコントロールComboBoxは Windows メッセージング システムに依存しているため、この動作は断続的です。選択の変更やメッセージ ボックスとほぼ同時に、フォームの他の部分によって生成されるメッセージが数百 (場合によってはそれ以上、場合によってはそれ以下) になる場合があります。大量のメッセージがある場合、システムは一部の処理に失敗する可能性があるため、選択されたインデックスは変更されません。

この問題を回避するための 2 つのオプション:

  • メッセージ ボックスを表示する新しいインデックスのサニティ チェックのSelectedIndex に設定します。i
  • BeginInvoke(以下の例)を使用して、サニティチェックを非同期で行います。システムが変更された選択されたインデックスのメッセージ処理を完了した後。

使い方はひとつBeginInvoke:

comboBox.SelectedIndex = i;

// Sanity check new index i after message processing for the combo box.
comboBox.BeginInvoke(delegate()
{
    if (/* sanity check fails */)
    {
        MessageBox("Error");
    }   
});

編集:Application.DoEvents別の回答が示唆するように、を使用して必要な動作を得ることができますが、私はこのアプローチを避けます。

于 2013-11-07T08:27:54.667 に答える
1

私の賭けは、その選択を変更したときに発生するイベントは、 を開く前に処理されていないということですMessageBox

これを追加してみてください:

Application.DoEvents();

...電話MessageBox.Show();して、それが役立つかどうかを確認する前に。その場合は、次の方法で、コントロール自体を同期的に再描画するように試みることができます。

comboBox.Refresh();

comboBox.Invokeスレッドを実行している場合は、試すことができます。また、PerformLayout/FormではControl、ペイント メッセージを待つのではなく、これらの種類のことがすぐに発生するように強制することがあります。

AMessageBox.Showは、トラック内のすべてのフォーム処理を停止します。最終的な解決策は、コンボボックスが必要なすべてのことを実行したことが確実な場合に、別の場所に配置することです。

于 2013-11-07T03:30:24.127 に答える
1

のソースとしてオブジェクトがある場合は、SelectedValueとを使用してそれを行うことができます。SelectedItemComboBox

この記事をご覧ください: SelectedValue、SelectedValuePath、SelectedItem & DisplayMemberPath について理解する。実行できるコード例もあります。

記事から:

SelectedItem : thelist/combobox/container で現在選択されている項目を返します。ご覧のとおり、これはオブジェクトです (私のリストにはオブジェクトが含まれているため)。List/Combobox/etc に文字列のリストが含まれている場合、それは文字列になります。int が含まれる場合は int になります。

SelectedValuePath : これを設定すると、プロパティ SelectedValue は、ここで選択したプロパティの値を返します。この例では、「ShapeColor」を選択すると、SelectedValue はシェイプ オブジェクト全体ではなく、色のみを返すようになります。

SelectedValue : オブジェクトの一部のみが必要な場合は、上記のプロパティを設定すると、そのプロパティの値がここで取得されます。SelectedValuePath を使用しない場合は、SelectedItem を使用した場合と同じであることに注意してください。

DisplayMemberPath : これをオブジェクトのプロパティに設定すると、クラス名または Class ToString() メソッド (常に提供する必要がある) を表示する代わりに、クラスが選択されたときに GUI にそのプロパティが表示されます。この項目 5 を見てください。本の目次)。

免責事項:私は記事の著者です...

于 2013-11-07T00:20:48.003 に答える