TabItemに複数のを表示するサポートツールに取り組んでいますTabControl。それぞれTabItemが従業員を表し、これらの各従業員の中に、追加のを含むTab別の従業員がいます。これらは、その従業員のOutlookフォルダを表します(「作業中」、「完了」など)。これらの各フォルダには、そのOutlookフォルダに関連するのにバインドされたが含まれています。これらは膨大なコレクションではありません。1つあたりのアイテムはわずか12個程度です。合計すると、すべてのアイテムで100個程度になる可能性があります。TabControlTabItemTabItemTabItemListBoxObservableCollectionMailItemListBoxTabItem
私が現在アプリケーションを構築している方法は、アプリが起動し、適切な従業員タブとサブタブが画面に表示されることです。このプロセスはかなり迅速で、私は満足しています。Global.System.TimerすべてのフォルダーTabItemのコードビハインドが同期されるスタティックを作成しました。したがって、5分ごとに、アプリケーションはすべてをクリアしObserverableCollection、Outlookフォルダを再スキャンします。
問題は、スキャンプロセスによってアプリケーションが停止することです。を使用してBackgroundWorkerOutlookからメールをバックグラウンドプロセスとして収集し、List<MailItem>オブジェクトをRunWorkerCompletedメソッドに渡してthis.Dispatcher.BeginInvoke、それぞれをクリアするプロセスを実行しObservableCollectionてから、アイテムをList<MailItem>後ろからに追加しようとしましたObservableCollection。これDispatcherを低い優先度に設定しました。
ListBoxそれにもかかわらず、アプリケーションはスキャン/入力プロセス中に非常に不格好な感じです。私はこれをより良く設計する方法がはっきりしていません、そして私はこれにいくらか新しいことを認めます。それぞれのをクリアするObservableCollectionのは非効率的ですが、Outlookのフォルダー変更イベントは特に信頼できるものではないため、すべてのが表示されるように、ブルートフォース再スキャンを時々実行する必要がありますMailItem。
以下は、を含むWPFコントロールのコードですListBox。ListBoxこれらのコントロールは一度に約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);
}
}
}