我正在开发一种支持工具,该工具TabItem
在TabControl
. 每个TabItem
代表一个员工,在每个员工Tab
s 中都有另一个TabControl
包含额外TabItem
的 s。这些TabItem
s 代表该员工的 Outlook 文件夹(如“正在工作”、“已完成”等)。这些文件夹TabItem
中的每一个都包含一个ListBox
绑定到ObservableCollection
属于MailItem
该 Outlook 文件夹的一个。这些不是庞大的收藏品——每个ListBox
. 尽管总的来说,在所有TabItem
s 中可能有 100 个左右的项目。
我目前构建应用程序的方式是启动应用程序并使用适当的员工选项卡和子选项卡填充屏幕。这个过程相当快,我很高兴。我创建了一个静态Global.System.Timer
,所有文件夹TabItem
的代码隐藏都与之同步。因此,应用程序每 5 分钟将清除所有ObserverableCollection
s 并重新扫描 Outlook 文件夹。
问题是扫描过程会使应用程序停止。我曾尝试使用 aBackgroundWorker
从 Outlook 收集邮件作为后台进程,然后将一个List<MailItem>
对象传递给一个RunWorkerCompleted
方法,该方法然后运行一个this.Dispatcher.BeginInvoke
清除相应的进程的进程,ObservableCollection
然后将项目从List<MailItem>
后面添加到ObservableCollection
. 我什至将其设置Dispatcher
为较低的优先级。
尽管如此,该应用程序在扫描/填充ListBox
过程中感觉非常笨重。我不清楚如何更好地设计它,我承认我对此有些陌生。我意识到清除每个ObservableCollection
s 效率低下,但 Outlook 文件夹更改事件并不是特别可靠,所以我需要每隔一段时间进行一次强力重新扫描以确保所有MailItem
s 都被表示。
下面是我的 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);
}
}
}