3

私は ComboBox を持っていますが、これを再設定すると、かなり時間がかかるようです。プロファイリングを行った後、ほとんどの時間が ComboBox.Items.AddRange(Array) メソッドに費やされていることがわかりました。ComboBox の再作成を実行する方法を示すメソッドの例を以下に示します。

public void Repopulate(IList<MyType> sortedList)
{
    MyComboBox.BeginUpdate();

    try
    {
        MyComboBox.Items.Clear();
        MyComboBox.Items.AddRange(sortedList.ToArray());
    }
    finally
    {
        MyComboBox.EndUpdate();
    }
}

sortedList には約 280 個の項目が含まれており、最大 53 個の ComboBox を再設定する必要があります。そのため、これらすべてのコントロールを再設定するにはかなりの時間がかかる可能性があり (高スペックのマシンで約 700 ミリ秒、低スペックのマシンで約 8000 ミリ秒)、私の要件には遅すぎます。sortedList を新しい IList に追加しようとしましたが、(私の高スペックのマシンでは) 約 1 ミリ秒かかりました。

ComboBox の再作成にかかる時間を大幅に短縮する必要があります。理想的には、IList と同様の時間ですが、パフォーマンスの向上は適切です。これまでのところ、再作成の速度を改善する方法を見つけることができませんでした。

ComboBox の再作成にかかる時間を短縮する方法について、誰かアイデアはありますか?

4

4 に答える 4

1

問題は、コンボボックスのSortedプロパティを有効にしたことが原因である可能性があります。これを有効にしてコンボボックスを呼び出すとAddRange、これらのアイテムがすべて並べ替えられますが、アイテムが既に並べ替えられている場合は不要です。

私の主張を証明するために、10,000 個の並べ替えられた int とAddRange. 唯一の違いは、1 つのコンボボックスではSortedプロパティが有効になっていて、もう 1 つのコンボボックスでは有効になっていないことです。AddRange結果の呼び出しのミリ秒単位の時間は次のとおりです

notSortedCombo: 5ms
sortedCombo: 1140ms

これはあなたの問題でしょうか?sorted プロパティが有効になっているコンボボックスを 53 個用意できますか?

于 2012-05-16T13:20:10.587 に答える
1

AddRange既に呼び出しBeginUpdateておりEndUpdate、その内部にあるため、自分で呼び出しても何も得られません。

これにより、数ミリ秒短縮されました。

public void Repopulate(IList<string> sortedList) {
  comboBox1.BeginUpdate();
  comboBox1.Items.Clear();
  foreach (string item in sortedList) {
    comboBox1.Items.Add(item);
  }
  comboBox1.EndUpdate();
}

より大きな問題は、おそらくデザインにあります。53 個のコンボ ボックスは、ユーザーにとって大量のコンボ ボックスです。ユーザーは、53 個のコントロールすべてを一度に操作することはできません。少しハックして、コンボ ボックスに表示される値 (1 項目) を入力し、コントロールがフォーカスされるか、バックグラウンド タイマーでリストに入力することができます。

ただし、画面上のコントロールの数を減らすことを検討してください。空白は良いことだと考えられています。

于 2012-05-16T13:38:15.307 に答える
0

FormattingEnabledコンボボックスのプロパティを次のように変更することで、パフォーマンスを向上させることができますFalse

True問題は、デザイナーでアイテムを「手動で」指定せず、プログラムで追加するかのように Visual Studio が保持することです。

試してみてください、それは私にとって問題を解決しました

于 2013-02-03T10:47:26.273 に答える
0

UI の仮想化について: 仮想化は WPF ( Example ) と WinForms の両方に存在します。ただし、ListView、DataGridView、TreeView など、一部のコントロールのみがサポートされています。これらは、大量のデータ用に設計されたコントロールです。可能であれば、これらのコントロールのいずれかに切り替えることができます。

すべてのコントロールが同時に画面に表示されていますか? おそらく、表示されているものだけを更新すると役立つでしょう。

別の方法は、コンボ ボックスを非同期的に更新することです。運が良ければ、.NET で新しい async/await を扱うことができれば、これは簡単に実行できます。手動で行う場合は、1 つのコンボボックスを更新し、次のコンボボックスの更新を数ミリ秒後にスケジュールすることができます (タイマーまたは TPL を使用します)。このようにして、更新が行われている間、UI は少なくとも応答性を保ちます。

もう 1 つの方法は、ユーザーが特定の ComboBox にフォーカスしたときにのみリストを更新することです。ユーザーが ComboBox を使用している場合にのみコンテンツが表示されるため、通常はコンテンツを更新する必要はありません。

データを更新する前に、コンボボックスを非表示にすることもできます。または、コンテンツの変更中に UI を再描画しないようにウィンドウに指示することもできます ( StackOverflow のトピックはこちら)。しかし、これが本当にパフォーマンスを向上させるかどうかはテストしていません。

于 2012-05-16T15:39:28.133 に答える