2010-05-04 9 views
8

मेरी समस्या यह है कि मुझे WPF में ListBox में बहुत सारी चीज़ें जोड़ने की आवश्यकता है। WinForms में आप केवल BeginUpdate() का उपयोग करेंगे; विधि, सब कुछ जोड़ें, और अंत में एंडअपडेट() का उपयोग करें; विधि।WPF में समकक्ष प्रारंभ करें?

तो, मैं एक WPF सूची बॉक्स में ड्राइंग को तब तक कैसे रोकूं जब तक कि प्रत्येक आइटम जोड़ा नहीं जाता है और फिर सबकुछ एक ही समय में खींचा जाता है?

उत्तर

5

ऐसा लगता है जैसे आप प्रोग्रामिंग रूप से आइटम को अपने सूची बॉक्स में एक-एक करके जोड़ सकते हैं। एक बेहतर तरीका उन वस्तुओं को स्टोर करना होगा जिन्हें आप मॉडल में प्रदर्शित करना चाहते हैं, और मॉडल को सूची बॉक्स के डेटा संदर्भ में बाध्य करें। यह डब्ल्यूपीएफ को प्रतिपादन अद्यतनों का ख्याल रखने की अनुमति देगा।

यदि आप प्रश्न में अपने एक्सएएमएल और कोड के स्निपेट जोड़ते हैं (हमें यह दिखाने के लिए कि आप वर्तमान में क्या कर रहे हैं), तो हम एक बेहतर उत्तर प्रदान करने में सक्षम हो सकते हैं।

संपादित करें: एक बहुत ही सरल उदाहरण जोड़ा गया।

यहाँ एक उदाहरण है कि मुख्य विंडो (देखें) और उसके बाद XAML घोषणा करता है कि ListBox के डेटा दृश्य मॉडल की नंबर संपत्ति के लिए बाध्य है के लिए एक दृश्य मॉडल बांधता है।

MainViewModel.cs

public class MainViewModel 
{ 
    public IEnumerable<int> Numbers 
    { 
     get { return Enumerable.Range(1, 1000); } 
    } 
} 

MainWindow.xaml

<Window 
    x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="350" 
    Width="525" 
    > 
    <ListBox ItemsSource="{Binding Numbers}"/> 
</Window> 

MainWindow.xaml.cs

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = new MainViewModel(); 
    } 
} 

अगर आप अभी डब्ल्यूपीएफ के साथ शुरुआत कर रहे हैं, तो मैं अत्यधिक एडम नाथन द्वारा Windows Presentation Foundation Unleashed की सिफारिश कर सकता हूं। यह एक महान किताब है और यह बूट करने के लिए रंग में है। इसके बाद अन्य पुस्तकें पढ़ना विजुअल स्टूडियो का उपयोग करने के बाद नोटपैड पर वापस जाने जैसा है।

इस मॉडल-व्यू-व्यू मॉडेल सामान पर और अधिक के लिए, जोश स्मिथ की Advanced MVVM पुस्तक देखें।

+0

हां, मैं प्रोग्रामबॉक्स में सूची बॉक्स में आइटम जोड़ रहा हूं। ठीक है, दिखाने के लिए बहुत अधिक कोड नहीं है, क्योंकि मैंने अभी तक पूरे एप्लिकेशन को कोड नहीं किया है, मैं बस सूची बॉक्स का उपयोग करके इसे कैसे कर सकता हूं और निम्न कोड: (int i = 0; i <1000; i ++) { lbQuery.Items.Add (i); } वैसे भी, क्या आप मुझे अपने समाधान का कोड उदाहरण दे सकते हैं? – Lith

+0

+1, उन्हें पहले सूची में बनाना, बेहतर होगा। जब तक यह असंभव न हो, तब आपको प्रत्येक ऐड के लिए रेड्रा के ओवरहेड के साथ रहना होगा। –

+1

यदि आप पूरी सूची को एक बार में जल्दी से पॉप्युलेट कर सकते हैं तो आपको बाध्यकारी से पहले ऐसा करना चाहिए ... यदि नहीं, तो यदि आप बैच-एट-ए-टाइम या इसी तरह जोड़ सकते हैं तो आपके पास प्रत्येक एड के लिए एक रेड्रो नहीं होना चाहिए। –

12

डिस्पैचर का सही ढंग से उपयोग करें।

आपको डिस्पैचर थ्रेड से अपने Listbox (या उसके डेटा स्रोत) में चीज़ें जोड़नी होंगी, अन्यथा यूआई विस्फोट हो जाएगा। जब आप ऐसा करते हैं, तो आप या तो उस धागे पर पहले से ही एक विधि में हैं (उम्मीद है कि अधिक संभावना है) आप पृष्ठभूमि थ्रेड में हैं और आइटम जोड़ने के लिए Dispatcher.BeginInvoke का उपयोग कर रहे हैं।

जब आप डिस्पैचर में अपडेट को लात मारते हैं, तो प्राथमिकता के रूप में Dispatcherpriority.Normal का उपयोग करें। डिस्पैचर में कार्य आइटमों की कतार है और आपकी Normal आइटम उस कतार में उच्च (शायद आश्चर्यजनक रूप से) धक्का देगी।

कोड का बिट जो डेटा अंतर्निहित डेटा बदलता है, DispatcherPriority.DataBind पर चलता है, जो Normal से कम है। इसका अर्थ यह है कि डेटा बाध्यकारी आमतौर पर अपडेट नहीं किया जाएगा जब तक कि आपके सभी आइटम जोड़े नहीं जाते हैं (या वैकल्पिक रूप से, यदि आपके आइटम जोड़ने के लिए लंबा समय लगता है, तो यह तब हो सकता है जब डिस्पैचर आइटम जोड़ने के बीच निष्क्रिय हो)।

वास्तव में आपके नियंत्रण को प्रस्तुत करने वाले कोड का थोड़ा सा (कहें, जब इसका बाध्यकारी सिग्नल अपडेट होता है) DispatcherPriority.Render पर चलता है और बाध्यकारी से भी कम प्राथमिकता है। इसका मतलब है कि आपका नियंत्रण केवल तब प्रस्तुत करेगा जब डिस्पैचर अपडेट करने के लिए बाइंडिंग से बाहर हो गया है, जो बदले में तभी होगा जब डिस्पैचर प्रक्रिया से जोड़ता है-प्रक्रिया में जोड़ता है।

यदि यह अजीब लगता है, तो याद रखें कि प्रत्येक परत (अपडेट - बाइंडिंग - रेंडर) नीचे की परत पर एक रूपक ध्वज सेट करने का कारण बनती है - आपको दस बाइंडिंग नहीं मिलती हैं और फिर दस रेंडर नहीं होते हैं। यदि आपका आइटम जोड़ता है, तो आप अपने सभी जोड़ों को एक बाइंड और एक रेंडर के बाद प्राप्त करेंगे - जो सही है।

असल में: यदि आप डिस्पैचर का इरादा रखते हैं तो आपके पास चिंता करने की कोई बात नहीं होगी। ऐसा लगता है कि डिस्पैचर पर अपेक्षाकृत कम प्राथमिकता के रूप में प्रस्तुत करना गलत है, लेकिन वास्तव में, यह बहुत चालाक है :-)

3

यह देखते हुए कि आप बड़ी सूचियों के साथ काम कर रहे हैं, तो आप WPF UI वर्चुअलाइजेशन में देखना चाहते हैं। यहाँ यह के बारे में ब्लॉग पोस्ट की एक अच्छी श्रृंखला है:

http://blogs.msdn.com/dancre/archive/tags/VirtualizingTilePanel/default.aspx

आम तौर पर आप होगा संग्रह में आइटम और एक लिस्टबॉक्स नियंत्रित करने के लिए है कि संग्रह डेटाबाउंड है। सूची बॉक्स, अगर सही तरीके से किया जाता है, तो जो आइटम जोड़े जा रहे हैं उन्हें रीफ्रेश नहीं करना चाहिए और दिखाई नहीं दे रहे हैं।

संबंधित मुद्दे