2009-03-20 17 views
6

私はかなり複雑で大規模なアプリケーションを使用しているので、データの読み込みや読み込みに手間がかかります。長い時間がかからないComboBoxにアイテムを追加するスピーディーな方法はありますか?私のP3 3.2GHzでは、次のスニペットで約32,000アイテムを追加しました。 (MasterCIListは、通常20〜30バイトの文字列を持つStringListです)。ダウンVCLにDelphiコンボボックスのスピードにアイテムを追加する

with LookupComboBox do 
begin 
    Items.BeginUpdate; 
    Items.Clear; 
    for i := 0 to MasterCIList.Count - 1 do 
    Items.Add(MasterCIList[i]); 
    Items.EndUpdate; 
end; 

掘削は、TComboBoxStrings.Addで、 結果への呼び出しがあることが表示されます。=のSendMessage(ComboBox.Handle、CB_ADDSTRING、0、倍長(PChar型(S)));

私はこれが本当に時間を費やしていると思っています(大丈夫、私はそれが分かります)。より迅速なアイテムを追加する別の方法はありますか?どんな高速コンボボックスもありますか?私はTMSコンポーネントを持っていますが、TComboBoxの拡張機能のようです。

例えば、私はPlusMemoを持っています。このPlusMemoは、TMemoの完全な書き換えであるようです。 PlusMemoに簡単に1秒間に100万行追加できます。 TMemo、私はそうは思わない。

ありがとうございました!

+4

答えはありませんが、なぜコンボボックスに32,000アイテムが必要ですか?多くのデータを保存するのは恐ろしい方法です。 –

答えて

1

おそらくcmb.Items.Assign(myStringList)が役立ちます。

私はそれを試したことはありませんが、項目の数を設定してオーナーの描画を設定することによって、コンボボックスを仮想的に読み込む方法があるかどうかを確認することができます。この狂気のアイデアを容赦してください。しかし、私はこれが何とか利用可能であると聞いてきたと思います。無関係:これはPalm OSでのやり方です。コンボボックスをロードする方が速いのは、すべてロードしないことです... ;-)

答えはありませんが、どうしてでしょうかコンボボックスに32,000アイテムありますか?多くのデータを保存するのは恐ろしい方法です。

私は同意します。それは悪い練習です...

17

申し訳ありませんが、私は迷惑だが、32,000品目のTComboBoxはリモートでも「使用可能」であるとは思っていません---それは遅い理由があります。これを行うつもりはありませんでした。

データをフィルタリングし、サブセットのみをロードする可能性はありますか?より具体的には、私が取り組んできた特定のデータベースアプリケーションでは、ユーザーは人を検索できます。ユーザーは少なくとも3文字または4文字の名前を入力できるようにしてから、結果をリストボックスに返すようにします。これにより、検索フォームのユーザビリティが大幅に向上し、プロセス全体が大幅にスピードアップしました。

同様の方法で対応できますか?

また、まったく別のテイクでは、おそらくVirtualTreeViewコンポーネントを見ることができます---直接使用またはインスピレーションのいずれかを行います。

+0

これは良いヒントです。既に入力された文字で始まるようにフィルタリングされたOnDropDownハンドラに文字列を追加することがあります。このようにして、ユーザは遅延に影響を与えます。いずれにしても、32000項目のルックアップリストは、即座に入力されても使用できません。 – mghie

3

私は32Kの項目がコンボボックスに持ってとんでもない量であること...言われて、あなたが最初のTStringListに項目を追加してみてくださいし、[開始/ EndUpdateメソッドとAddStringsの組み合わせを使用する場合がありますことに同意:

SL := TStringList.Create; 
try 
    // Add your items to the stringlist 
    ComboBox.Items.BeginUpdate; 
    try 
    ComboBox.Items.AddStrings(YourStringList); 
    finally 
    ComboBox.Items.EndUpdate; 
    end; 
finally 
    SL.Free; 
end; 

コードはコンパイルされますが、それ以上はテストしませんでした。私はコンボボックスやリストボックスに数十以上のアイテムを追加する必要はないと感じました。それ以上のアイテムが必要な場合は、リストを作成する前にフィルタリングしてアイテムが少なくなるようにする方法があります。

ちょうど好奇心の邪魔をして、ユーザーはどのようにして多くのアイテムを並べ替えて決定を下すと思いますか?

1

もう一度私です。私が必要とする32,000のアイテムを追加しています。それは私のアプリケーションではたくさんのアイテムを持っている多くのコントロールの1つです。私はその多くのアイテムを持っている必要があります。それはちょうど良いものを見て動作します。実際には完璧に。私は物事を最適化しようとしています。ユーザーは特定の論理的順序にある​​ので、物事はうまくいきます。

AssignとAddStringsを使ってこれまで私が思っていたことは、最終的にSendMessage呼び出しでAddに終わることです。だから私は見続けるだろう。

フィードバックいただきありがとうございます。

+1

まず、このような「回答」を投稿するのは間違っています。元の投稿を編集します。第二に、私は20年以上のプログラミングを続けてきており、15+のためのWinアプリケーションは、非常に複雑なアプリケーションをいくつか実行したことがあり、コンボボックスの1K項目の必要性は決して見つけられていません。しかし、あなた(そしてあなたのアプリのユーザー)には幸運です。 –

+0

ケンと同意します。明らかにするには、本当にあなたの質問に対する回答であれば、回答を投稿するのは良いことです。コメントがあれば質問を編集してください。 – Argalatyr

0

おそらく、バックエンドでデータベースエンジンを使用し、データ対応コンポーネントを使用することができます。その後、物事ははるかに迅速に使用可能になります。もしあなたが何を達成しようとしているのかを説明しようとするなら、私たちはあなたをさらに助けるでしょう。どんな場合でも、あなたのUIデザインは、が奇数と言われています。そして、これはおそらくEmbarcadero forumsがあなたをより良く助けるでしょう。

0

私はこれを別のやり方で実装します。最初にコンボボックスコントロールを削除し、テキストボックスコントロールを取得し、カスタムソースストリングコレクションがカスタムソースに割り当てられるようにオートコンプリートを割り当てます。32k items.Iコントロールの検証に関する新しいクエリから選択した値を取得します。

これで、コンボボックスの機能を置き換えることができます。大抵について32K項目の人々はスクロールいけないが、彼らは唯一のAddStringsを使用MasterCIList items.after完全な追加項目を追加するための

1

..使用backgroundworkerをキーストロークを入力維持し、当社独自の自動完全なソースによってcatchedされます。

procedure TForm2.BackgroundWorker1Work(Worker: TBackgroundWorker); 
var 
    I: Integer; 
begin 
    MasterCIList.BeginUpdate; 
    try 
    MasterCIList.Capacity := 32 * 1024; // if derminate count of items 
    for I := 1 to 32 * 1024 do 
    begin 
     MasterCIList.Add(IntToStr(I)); 
     { if need progess } 
     if I mod 300 = 0 then 
     Worker.ReportProgress((I * 100) div MasterCIList.Capacity); 
     { if need cancelable } 
     if (I mod 100 = 0) and Worker.CancellationPending then 
     Break; 

    end; 

    finally 
    MasterCIList.EndUpdate; 
    end; 

end; 

procedure TForm2.BackgroundWorker1WorkComplete(Worker: TBackgroundWorker; 
    Cancelled: Boolean); 
begin 

    LookupComboBox.Items.AddStrings(MasterCIList); 


// AddStrings use beginupdate..endupdate in itself 

end; 
2
var 
    Buffer: TStringList; 
begin 
    Buffer := TStringList.Create; 

    try 
    // --> Add items to Buffer here <-- 

    ComboBox.Items := Buffer; 
    finally 
    FreeAndNil(Buffer); 
    end; 
end; 

これは、我々は視覚的なコントロールを更新するために見つけた最速の方法です「コンボボックスまたはリストボックスに項目を追加高速化」。

VCLはBeginUpdate、Clear、およびEndUpdateを内部的に行います。

私を信じていない場合は、プロファイルしてください。

関連する問題