2012-12-14 15 views
5

मेरे पास मेरे आवेदन में डेटा देखने के लिए विशाल तालिका के साथ एक दृश्य है। डेटा दो नेस्टेड यूनिफॉर्मग्रिड्स में प्रदर्शित होता है। UniformGrids ItemControls में ItemPanels हैं और कुछ ViewModels से बंधे हैं। निम्नलिखित छवि और कुछ उदाहरण XAML-कोड देखें:विशाल यूनिफॉर्मग्रिड्स में प्रदर्शन को कैसे संभालें?

view and viewmodel http://img593.imageshack.us/img593/8825/stackoverflowuniformgri.png

<!-- The green boxes --> 
<ItemsControl ItemsSource="{Binding BigCells}"> 

    <ItemsControl.ItemPanel> 
    <PanelTemplate> 
     <UniformGrid /> 
    </PanelTemplate> 
    </ItemsControl.ItemPanel> 

    <ItemsControl.ItemTemplate> 
    <DataTemplate> 

     <!-- The blue boxes --> 
     <ItemsControl ItemsSource="{Binding SmallCells}"> 
     <ItemsControl.ItemPanel> 
      <PanelTemplate> 
      <UniformGrid /> 
      </PanelTemplate> 
     </ItemsControl.ItemPanel> 
     </ItemsControl> 

    </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

अब, मैं मेरे विचार आकार बदलने योग्य होना चाहते हैं, लेकिन यह अच्छी तरह से सभी के बाद से हर एक छोटे से बॉक्स के लेआउट की जाती है पर प्रदर्शन नहीं करता।
यह कम से कम एक बार बॉक्स आकार के लिए किया जा सकता है, क्योंकि यह सभी बक्से के बराबर है।

डब्ल्यूपीएफ में बड़ी मात्रा में नियंत्रण प्रदर्शित करने के लिए सबसे अच्छा अभ्यास क्या है/मैं अनुकूलित कहां से शुरू कर सकता हूं? कीवर्ड पहले से ही मुझे डब्ल्यूपीएफ में यूनिफॉर्मग्रिड्स के प्रदर्शन अनुकूलन की खोज जारी रखने में मदद करेंगे।

उत्तर

8

मुझे एक ही समय में बहुत सी WPF DataGrid का उपयोग करते समय भी एक ही समस्या आई है।

संसाधन शब्दकोश

  • संसाधन शब्दकोशों
  • बाइंडिंग
  • अगर आप बुनियादी WPF सावधान किया जा रहा बिना सुविधाओं का उपयोग उन प्रमुख बाधाओं हो सकता है: यह अंत में दो प्रमुख मुद्दों के लिए नीचे आया।

    मेरे मामले में, ItemsControl में एक भी तार्किक पुस्तक है कि मेरे DataGrids युक्त था के लिए, मैं कुछ हो रही थी 10 लाखों लोगों की तरह GetValue और GetValueWithoutLock ResourceDictionary पर करने के लिए कहते हैं। प्रक्रिया के लिए 1 सेकंड से अधिक।

    • गतिशील संसाधन पुनः प्राप्ति: आप ControlTemplates संसाधन कुछ शब्दकोशों में रखा संसाधन है, तो और अधिक आम तौर पर, और आप {DynamicResource ...} से उन तक पहुँच, उन्हें हटाने

      ResourceDictionary पहुंच का यह प्रमुख संख्या विभिन्न स्रोतों के कारण हुई थी । कहीं कुछ स्थिर है और उन्हें सीधे acces।

    • शैली लाने: यदि आपके पास उपयोग किए जाने वाले विभिन्न दृश्यों पर कोई शैली नहीं है, या यदि आपके पास शैली है लेकिन FrameworkElement.OverridesDefaultStyle संपत्ति सेट नहीं की गई है, तो WPF सभी संसाधनों में नियंत्रण से मेल खाने वाली शैली ढूंढने का प्रयास करेगा, जिसके परिणामस्वरूप संसाधन शब्दकोशों में बहुत से उपयोग में। इससे बचने के लिए, अपने नियंत्रण के सभी नियंत्रण टेम्पलेट्स को ओवरराइड करना सुनिश्चित करें, और प्रत्येक नियंत्रण पर Style={x:Null} सेट करें (यदि आपको नियंत्रण के लिए शैली की आवश्यकता है, तो इसे अपने नियंत्रण में इनलाइन करें, और OverridesDefaultStyle = true जोड़ें)
    • लागू डेटा टेम्पलेट्स: लागू डेटा टेम्पलेट बहुत उपयोगी है लेकिन बहुत से दूर हैं। आवेदन करने के लिए DataTemplate की तलाश करते समय, WPF एक बार फिर आपके संसाधन शब्दकोशों को ब्राउज़ करेगा ताकि DataTemplate आपके व्यू मॉडेल प्रकारों से मेल खा सके। समाधान DataTemplate चयनकर्ता का उपयोग प्रत्येक दृश्य के लिए व्यूमोडेल से जुड़ा हुआ है, और सही DataTemplate को पुनर्प्राप्त करने के लिए एक अनुकूलित तरीका लागू करना है। (मेरे पास व्यक्तिगत रूप से मेरे डेटा के लिए कुछ स्थिर फ़ील्ड हैं टेम्पलेट जो मैं संसाधन डिक्शनरी से केवल एक बार पुनर्प्राप्त करता हूं, और एक अनुकूलित DataTemplateSelector जो उन्हें आवश्यकतानुसार देता है।)

    बाइंडिंग

    बाइंडिंग बहुत उपयोगी है, लेकिन बहुत महंगे हैं, स्मृति बुद्धिमान और प्रदर्शन बुद्धिमान। एक बहुत ही समझदार माहौल में - एक प्रदर्शन बिंदु से - आप केवल सावधान किए बिना उनका उपयोग नहीं कर सकते हैं। उदाहरण के लिए, बाइंडिंग प्रत्येक बाइंड ऑब्जेक्ट के लिए 3 वीक रेफरेंस बना सकती है, प्रतिबिंब का उपयोग कर सकती है, आदि। अंत में मैं अपने डेटाकॉन्टेक्स्ट की प्रॉपर्टी चेंजेड इवेंट पर लगभग सभी बाध्यकारी और प्लग किए गए ईवेंट हैंडलर को हटाने के साथ समाप्त हुआ। जब DataContext मेरे नियंत्रणों में परिवर्तन करता है (आपके पास DataContextChanged ईवेंट है) तो मैं परीक्षण करता हूं कि मेरा DataContextINotifyPropertyChanged का समर्थन करता है, और यदि ऐसा है, तो मैं PropertyChanged ईवेंट पर ईवेंट हैंडलर संलग्न करता हूं और आवश्यकतानुसार गुण अपडेट करता हूं। (मेरे पास केवल एक ही रास्ता बाइंडिंग था, इसलिए मैंने चीजों को करने का यह तरीका चुना, लेकिन अन्य समाधान भी हैं)।

    एमवीवीएम और डब्ल्यूपीएफ का उपयोग करते समय बाइंडिंग का उपयोग न करने में निराशाजनक लग रहा है, लेकिन वास्तव में मेरे मामले में बाइंडिंग को अनुकूलित करने का कोई तरीका नहीं था।

    अंतिम बात: यदि आपके पास Freezable ऑब्जेक्ट्स (उदाहरण के लिए ब्रश की तरह) हैं, तो Freeze उन्हें संकोच न करें अगर आप कर सकते हैं।

    ये कुछ सलाह हैं जो आपको अपने कोड को अनुकूलित करने में मदद कर सकती हैं। वास्तव में क्या हो रहा है इसकी निगरानी करने और परिणामों के अनुसार अनुकूलित करने के लिए आपको एक प्रोफाइलर की आवश्यकता होगी (मैं हमेशा डॉटट्रेस का उपयोग करके सलाह देता हूं क्योंकि यह अब तक का सबसे अच्छा प्रोफाइलर है)।

    शुभकामनाएं!

+0

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

+0

निश्चित रूप से, मुझे बताएं कि यह कैसे चला जाता है! यह वास्तव में मेरे लिए एक अच्छा अभ्यास था क्योंकि मुझे अपने ब्लॉग पर एक प्रदर्शन पोस्ट लिखना है :) – Sisyphe

+0

हमारे पास सब कुछ के लिए संसाधन संसाधन हैं और एप्लिकेशन अभी भी बहुत तेज़ है।जिस तरह से हमने संपर्क किया, वह एक संसाधन (जैसे स्टाइल, वेक्टर, ब्रश इत्यादि) के लिए एक संसाधन शब्दकोश बना रहा था, फिर प्रत्येक दृश्य से हम केवल उन संसाधन शब्दकोशों को संदर्भित करते हैं जिन्हें आवश्यक हैं। समस्या एक समान ग्रिड है, क्योंकि यह वर्चुअलाइज नहीं करता है। – adminSoftDK

4

यदि आप एक ही आकार के सभी बक्से के बारे में सुनिश्चित हैं, तो आप हमेशा अपना खुद का UniformGrid कक्षा बना सकते हैं और MeasureOverride को केवल एक बच्चे को मापने के लिए ओवरराइड कर सकते हैं। मैं भी मेरे वर्तमान परियोजना में एक ही आकार के आंतरिक नियंत्रण के साथ कुछ बड़े UniformGrids लग सकती है, इसलिए अपने विचार मुझे intrigued है और मैं इसे बहुत जल्दी बाहर की कोशिश करने का फैसला किया:

मैं प्रेरणा के रूप में पेज़ॉल्ड के UniformGridAlmost वर्ग का इस्तेमाल किया है, लेकिन से subclassed UniformGridPanel के बजाय, पंक्तियों और स्तंभों के अवशिष्ट गुणों को डुप्लिकेट करने की आवश्यकता नहीं है। UniformGrid अपनी व्युत्पन्न कक्षाओं में पंक्तियों और स्तंभों की गणना संख्या को प्रचारित नहीं करता है, इसलिए मैंने Silverlight's UniformGrid class से कार्यान्वयन उधार लिया और UpdateComputedValues विधि का उपयोग किया।

MeasureOverride मेरी कक्षा में इस

protected override Size MeasureOverride(Size sizeAvailable) 
    { 
    if (InternalChildren.Count == 0) 
    { 
     return new Size(0, 0); 
    } 

    UpdateComputedValues(); 

    // Calculate a child size based on uniform rows and columns. 
    Size sizeChild = new Size(sizeAvailable.Width/ComputedColumns, 
           sizeAvailable.Height/ComputedRows); 

    // Assume children will measure to at least a comparable size. 
    UIElement child = InternalChildren[0]; 
    child.Measure(sizeChild); 

    double width = Math.Max(width, child.DesiredSize.Width); 
    double height = Math.Max(height, child.DesiredSize.Height); 
    return new Size(ComputedColumns * width, ComputedRows * height); 
    } 

तो की तरह लग रहा है, यहाँ किकर है, जब मैं 10000 TextBlocks के साथ एक ItemsControl पर यह परीक्षण किया है, UniformGrid की मेरी संस्करण तेजी से गया था, लेकिन केवल एक छोटी राशि के द्वारा (1% से कम - मैंने पुष्टि की कि MeasureOverride को कॉल लगभग 95% तेज है)। तो यह शायद सहायक नहीं है, लेकिन मैंने सोचा कि मैं अपना अनुभव साझा करूंगा। आपके अवलोकन में कि आपके मामले में एक समान लेआउट निर्धारित करने के लिए प्रत्येक बॉक्स को मापने की आवश्यकता नहीं है, लेकिन यह माप यह नहीं है कि इसे किस प्रकार दबाया जा रहा है। मुझे यकीन है कि ऐसा इसलिए है क्योंकि उन सभी नियंत्रणों को अभी भी तैयार करने की आवश्यकता है, इसलिए उन्हें बाद में मापा जाएगा। आपको सबसे अधिक संभावना संसाधन संसाधन/बाध्यकारी सुझाव से बहुत अधिक लाभ उठाने जा रहे हैं।

+0

मैंने अभी इस यूनिफॉर्म ग्रिड की कोशिश की है, और मेरे मामले में यह मानक वर्दी ग्रिड से लगभग 3 गुना तेज है। तो ड्राइंग का समय 20 सेकेंड से लगभग 7 सेकेंड तक गिर गया। – adminSoftDK

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