TabControl
'da birden çok TabItem
s görüntüleyen bir destek aracı üzerinde çalışıyorum. Her bir TabItem
, bir çalışanı temsil eder ve bu çalışanların her birinin içinde Tab
s'nin içinde TabItem
s bulunan başka bir TabControl
vardır. Bu TabItem
s, bu çalışanın ("Çalışma", "Tamamlandı" vb.) Outlook klasörlerini temsil eder. Bu klasörün TabItem
s her biri, bu Outlook klasörüne ait ObservableCollection
MailItem
s'ye bağlı olan bir ListBox
içerir. Bunlar büyük koleksiyonlar değil - sadece ListBox
'a göre bir düzine kadar ürün. Toplamda, tüm TabItem
lar arasında olmasına rağmen, muhtemelen 100 ürün olabilir.Birden çok Liste Kutusunu doldururken duyarlı bir WPF UI oluşturmanın yolu nedir?
Uygulamayı şu anda oluşturduğum yol, uygulamanın uygun çalışan sekmeleri ve alt sekmelerle ekranın patlaması ve doldurulmasıdır. Bu süreç oldukça hızlı ve mutluyum. Global.System.Timer
Statik TabItem
'un tüm kodlarının arka planda senkronize edildiği bir istatistik oluşturdum. Yani her 5 dakikada bir uygulama tüm ObserverableCollection
s temizleyecek ve Outlook klasörlerini yeniden tarayın.
Sorun, tarama işleminin uygulamayı durma noktasına getirmesidir. Sonra daha sonra ilgili ObservableCollection
temizler geri ObservableCollection
için List<MailItem>
öğeleri ekleyen this.Dispatcher.BeginInvoke
sürecini çalışan bir RunWorkerCompleted
yöntemine bir List<MailItem>
nesneyi geçmesi, bir arka plan işlemi olarak Outlook'tan posta toplamak için bir BackgroundWorker
kullanarak çalıştılar. Bu Dispatcher
'u bile daha düşük önceliğe ayarladım. Buna rağmen, uygulama tarama/popülasyon ListBox
işlemi sırasında çok rahatsız edici bir duygudur. Buna rağmen; Bunu nasıl daha iyi tasarlayacağımı açık değil ve bunun için biraz yeni olduğumu itiraf ediyorum. Ben her ObservableCollection
s temizlemenin, verimsiz olduğunu, ancak Outlook klasör değiştirme olaylarının özellikle güvenilir olmadığını fark ediyorum, bu yüzden tüm MailItem
s temsil edilmesini sağlamak için her defasında bir kez kaba bir güç yeniden tarama yapmak gerekir.
Aşağıda, ListBox
'u içeren WPF denetimi için kodum var. Bu ListBox
kontrolünün yaklaşık 10'unun aynı anda aktif olduğunu unutmayın. İhtiyaçlarınız için
// 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);
}
}
}
kadar 5000'den öğelerle klasörleri içerir Sekmeli görünüm posta okuyucu böyle az veri olan böyle büyük performans sorunları yaşıyorsanız garip biraz, ben benzer bir uygulama var gibi görünüyor ve bu Arayüzü asmak değil , Ne tür bir 'Timer'' 'GlobalStatics.Timer'',' 'BackgroundWorker'' gereksinimini ortadan kaldıran bir Threading.Timer' kullanırım, Bu posta Öğeleriyle ilişkili görüntüler var mı? –
RunWorkerCompleted işleyicisi, BackgroundWorker'ın oluşturulduğu iş parçacığında çalışmıyor mu? Bu durumda, kullanıcı arabiriminde olduğunuzdan beri UI iş parçacığı üzerinde kod çalıştırmak için bir Dispatcher kullanmanız gerekmemelidir. – Andy