TabControl
に複数のTabItem
を表示するサポートツールを開発中です。各TabItem
は従業員を表し、これらの従業員Tab
の中には、別のTabControl
があり、これにはさらにTabItem
が含まれています。これらのTabItem
は、その従業員のOutlookフォルダ(「作業中」、「完了済み」など)を表します。これらの各フォルダTabItem
には、ObservableCollection
のMailItem
にバインドされたListBox
が含まれています。このフォルダはOutlookフォルダに関連しています。これらは巨大なコレクションではなく、ListBox
ごとに12個ほどのアイテムしかありません。合計で、TabItem
には100アイテム程度あると思われます。複数のリストボックスにデータを入力する際のレスポンスWPF UIの作成の秘訣は何ですか?
私が現在アプリケーションを構築しているのは、アプリケーションが起動して、適切な従業員のタブとサブタブが画面に表示されるということです。このプロセスはかなり速く、私は満足しています。私はすべてのフォルダTabItem
のコードビハインドが同期されているStatic Global.System.Timer
を作成しました。したがって、アプリケーションはすべて5分ごとにObserverableCollection
をすべてクリアし、Outlookフォルダを再スキャンします。
問題は、スキャン処理によってアプリケーションが停止することです。私は、次いで、それぞれObservableCollection
をクリアバックObservableCollection
List<MailItem>
への項目を追加this.Dispatcher.BeginInvoke
プロセスを実行RunWorkerCompleted
方法List<MailItem>
オブジェクトを渡し、バックグラウンドプロセスとしてOutlookからメールを収集するBackgroundWorker
を用いて試みました。私はこのDispatcher
をより低い優先度に設定しました。
これにもかかわらず、アプリケーションはスキャン中に非常にclunky感じ/人口ListBox
プロセスです。私はこれをよりうまく設計する方法が不明であり、私はこれにいくらか新しいことを認めている。 ObservableCollection
のそれぞれをクリアするのは非効率ですが、Outlookフォルダの変更イベントは特に信頼できるものではないので、すべてMailItem
が確実に表示されるようにしばらく毎回再スキャンを実行する必要があります。
以下は、ListBox
を含むWPFコントロール用のコードです。これらのコントロールのうち約10個が同時にアクティブになることに注意してください。
// This entire UserControl is essentially a ListBox control
public partial class TicketListView : UserControl
{
private TicketList _ticketList; //this is the ObservableCollection object
private Folder _folder; // Outlook Folder
public TicketListView(Folder folder)
{
InitializeComponent();
_ticketList = this.FindResource("TicketList") as TicketList;
_folder = folder;
GlobalStatics.Timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
}
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Refresh();
}
private void Refresh()
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
List<MailItem> tickets = new List<MailItem>();
string filter = TicketMonitorStatics.TicketFilter(14);
Items items = _folder.Items.Restrict(filter);
try
{
foreach (MailItem mi in items.OfType<MailItem>())
{
tickets.Add(mi);
}
}
catch (System.Exception) { }
e.Result = tickets;
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
List<MailItem> tickets = e.Result as List<MailItem>;
this.Dispatcher.BeginInvoke(new System.Action(delegate
{
_ticketList.Clear();
PopulateList(tickets);
}));
BackgroundWorker worker = sender as BackgroundWorker;
worker.Dispose();
}
private void PopulateList(List<MailItem> ticketList)
{
foreach (MailItem mi in ticketList)
{
this.Dispatcher.BeginInvoke(new System.Action(delegate
{
_ticketList.Add(mi);
}), System.Windows.Threading.DispatcherPriority.SystemIdle);
}
}
}
は点で最大5000 +アイテムとフォルダが含まれ、タブ付きの見通しmailreaderあなたは、このような小さなデータでこのような大きなパフォーマンスの問題を抱えている奇数ビットが、私は同様のアプリを持っているようだし、これは、UIがハングアップしません。どのような 'Timer'が' GlobalStatics.Timer'なのか、 'BackgroundWorker'の必要性を排除する' Threading.Timer'を使用します。これらのメールアイテムに関連する画像もありますか? –
RunWorkerCompletedハンドラは、BackgroundWorkerが作成されたスレッドで実行されませんか?このような場合は、既にUIスレッド上にあるため、Dispatcherを使用してUIスレッドでコードを実行する必要はありません。 – Andy