मैं एक समर्थन उपकरण पर काम कर रहा हूं जो में एकाधिक TabItem
एस प्रदर्शित करता है। प्रत्येक TabItem
एक कर्मचारी का प्रतिनिधित्व करता है, और इनमें से प्रत्येक कर्मचारी Tab
एस के भीतर एक और TabControl
है जिसमें अतिरिक्त TabItem
एस है। ये TabItem
एस उस कर्मचारी के लिए आउटलुक फ़ोल्डर्स का प्रतिनिधित्व करते हैं (जैसे "वर्किंग", "पूर्ण", आदि)। इनमें से प्रत्येक फ़ोल्डर TabItem
एस में ListBox
है जो ObservableCollection
MailItem
एस से संबंधित है जो उस Outlook फ़ोल्डर से संबंधित है। ये विशाल संग्रह नहीं हैं - ListBox
प्रति केवल एक दर्जन या उससे अधिक आइटम। हालांकि, कुल मिलाकर, सभी TabItem
एस में अनुमानतः 100 आइटम या तो हो सकता है।एकाधिक ListBoxes populating जब एक उत्तरदायी WPF UI बनाने की चाल क्या है?
जिस तरीके से मैंने वर्तमान में एप्लिकेशन बनाया है वह यह है कि ऐप उचित कर्मचारी टैब और उप-टैब के साथ स्क्रीन को ऊपर खींचता है और पॉप्युलेट करता है। यह प्रक्रिया काफी तेज़ है और मैं खुश हूं। मैंने एक स्टेटिक Global.System.Timer
बनाया है कि सभी फ़ोल्डर TabItem
का कोड-बैक सिंक्रनाइज़ किया गया है। तो हर 5 मिनट में एप्लिकेशन सभी ObserverableCollection
एस साफ़ कर देगा और Outlook फ़ोल्डरों को फिर से स्कैन करेगा।
समस्या यह है कि स्कैन प्रक्रिया एप्लिकेशन को रोक देता है। मैं एक पृष्ठभूमि प्रक्रिया के रूप में आउटलुक से मेल इकट्ठा करने के लिए है, तो एक RunWorkerCompleted
विधि है कि फिर एक this.Dispatcher.BeginInvoke
प्रक्रिया है कि संबंधित ObservableCollection
को साफ करता है तो List<MailItem>
वापस ObservableCollection
करने से आइटम कहते हैं चलाता है के लिए एक List<MailItem>
वस्तु पारित एक BackgroundWorker
उपयोग करने की कोशिश की है। मैंने यह Dispatcher
को निम्न प्राथमिकता पर भी सेट किया है।
इसके बावजूद, एप्लिकेशन स्कैन/पॉप्युलेट ListBox
प्रक्रिया के दौरान बहुत घबराहट महसूस कर रहा है। मैं इस बारे में अस्पष्ट हूं कि इसे बेहतर तरीके से कैसे डिजाइन किया जाए और मैं मानता हूं कि मैं इसके लिए कुछ नया हूं। मुझे एहसास है कि ObservableCollection
एस में से प्रत्येक को साफ़ करना अक्षम है, लेकिन आउटलुक फ़ोल्डर परिवर्तन घटनाएं विशेष रूप से विश्वसनीय नहीं हैं, इसलिए मुझे सभी MailItem
एस का बीमा करने के लिए हर बार एक ब्रूट फोर्स फिर से स्कैन करने की आवश्यकता होती है।
नीचे WPF नियंत्रण के लिए मेरा कोड है जिसमें ListBox
शामिल है। ध्यान रखें कि इनमें से 10 में से ListBox
नियंत्रण एक साथ सक्रिय हैं।
// 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);
}
}
}
, टैब किए गए दृष्टिकोण mailreader कि तक 5000+ आइटम के साथ फ़ोल्डर्स शामिल थोड़ा अजीब आप इस तरह के कम डेटा के साथ इस तरह बड़ा प्रदर्शन के मुद्दों कर रहे हैं, मैं एक ऐसी ही ऐप्लिकेशन है, लगता है और इस यूआई लटका नहीं करता है , किस प्रकार का 'टाइमर' ग्लोबलस्टैटिक्स टिमर 'है, मैं' थ्रेडिंग टिमर 'का उपयोग करता हूं जो' पृष्ठभूमिवर्कर 'की आवश्यकता को समाप्त करता है, क्या इन मेल आइटम्स से संबंधित छवियां भी हैं? –
क्या RunWorker पूर्ण हैंडलर थ्रेड पर नहीं चला है जहां BackgroundWorker बनाया गया था? यदि ऐसा है तो आपको UI थ्रेड पर कोड चलाने के लिए डिस्पैचर का उपयोग करने की आवश्यकता नहीं है क्योंकि आप पहले ही यूआई थ्रेड पर हैं। – Andy