0

いくつかのグリッド、スタックパネル、およびテキストブロックで構成されるカスタム コントロールを作成しました。ListBoxアイテムとして使用したいもの。画像に示されているように、リストの各項目に複数行の情報を表示するために使用しています。コントロールの名前は ItemDetail です。

リストボックスのカスタム コントロール

リストを埋めるために、上の各ボタンをクリックすると、SQL クエリが作成されます (クエリには約 5 秒かかる場合があり、UI がフリーズしていることに気づきます)。

これを修正するために、SQL クエリに BackgroundWorker を使用し、クエリの結果の行が返されるたびに進行状況を報告しています。

private void Departamento_Click(object sender, MouseButtonEventArgs e)
    {
        Elementos_Lista.Items.Clear();
        BackgroundWorker _worker = new BackgroundWorker();
        _worker.WorkerReportsProgress = true;
        _worker.ProgressChanged += new ProgressChangedEventHandler(_worker_ProgressChanged);

        _worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
           //SQL query
           reglas.Consulta("cerrado='0' and grupo='3' order by fecha desc");   

            foreach (DataRow dr in reglas.Entidad.tabla.Rows)
            {
                _worker.ReportProgress(0, dr);
            }

        };
        _worker.RunWorkerAsync();
    }

また、BackgroundWorker の IsProgressChanged イベントを使用してデータを ItemDetail のインスタンスに追加し、それを ListBox に追加しています。

 void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        ItemDetail item = new ItemDetail((DataRow)e.UserState);
        Elementos_Lista.Items.Add(item);
    }

この方法では、操作にかかる時間が大幅に短縮されますが、それでもフリーズします。これは、クエリの各行が返された後に実行する必要がある UI の更新が原因です。BackgroundWorker では、UI スレッドではないため、個別のスレッドで ItemDetail コントロールにデータを追加できません。

多数のコントロールを一度にレンダリングするプロセスを高速化する方法や、それらを小さなバッチでリストに追加する方法はありますか?

4

1 に答える 1

2

ObservableCollectionリストコントロールにバインドする必要のあるデータをに追加し、データテンプレートを介してコントロールを生成できるようにします。仮想化を使用している場合、不要なコントロール(スクロールして表示されないコントロール)はすぐには作成されないため、操作が高速になります。 。

于 2012-04-20T15:37:38.900 に答える