TabItem
に複数のを表示するサポートツールに取り組んでいますTabControl
。それぞれTabItem
が従業員を表し、これらの各従業員の中に、追加のを含むTab
別の従業員がいます。これらは、その従業員のOutlookフォルダを表します(「作業中」、「完了」など)。これらの各フォルダには、そのOutlookフォルダに関連するのにバインドされたが含まれています。これらは膨大なコレクションではありません。1つあたりのアイテムはわずか12個程度です。合計すると、すべてのアイテムで100個程度になる可能性があります。TabControl
TabItem
TabItem
TabItem
ListBox
ObservableCollection
MailItem
ListBox
TabItem
私が現在アプリケーションを構築している方法は、アプリが起動し、適切な従業員タブとサブタブが画面に表示されることです。このプロセスはかなり迅速で、私は満足しています。Global.System.Timer
すべてのフォルダーTabItem
のコードビハインドが同期されるスタティックを作成しました。したがって、5分ごとに、アプリケーションはすべてをクリアしObserverableCollection
、Outlookフォルダを再スキャンします。
問題は、スキャンプロセスによってアプリケーションが停止することです。を使用してBackgroundWorker
Outlookからメールをバックグラウンドプロセスとして収集し、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);
}
}
}