2012-05-09 7 views
7

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

एक उत्तर स्वीकार करने के बाद मुझे यह लिंक प्राप्त हुआ: http://www.codeproject.com/Articles/23937/Paging-Data-with-DataGridView-in-VirtualMode। हालांकि यह डेटाबेस उदाहरण का उपयोग करता है, लेकिन मुझे जो चाहिए वह बेहतर है। मेरी सूची है कि डेटा मैं प्रदर्शित करने के लिए घोषित किया जाता है इस प्रकार है चाहता हूँ में शामिल होंगे:

List<ResultRow> captureResults = new List<ResultRow>(); 

एक ResultRow वस्तु के रूप में निम्नानुसार परिभाषित किया गया है:

/* Simplified */ 
public class ResultRow 
{ 
    private int first = 0; 
    private string second = ""; 
    private UInt64 third = 0; 
    private IPAddress fourth = null; 
    /* etc */ 

    public ResultRow() 
    { 
    } 

    public void Set (<the values>) //In actuallity a KeyValuePair 
    { 
     //field gets set here 
    } 

    public UInt64 Third 
    { 
     get { return third; } 
     set { third = value; } 
    } 

    /* etc. */ 

}

लेख के बाद ऊपर उल्लेख किया है, मैं एक परिणाम RowCache बनाया। ।।

/* Page size set to 100. */ 
ResultRowCache _cache = new ResultRowCache(PAGE_SIZE, captureResults); 

मेरी प्रपत्र लोड घटना पर मैं निम्नलिखित (इस समस्या से संबंधित मैं भी एक ईवेंट हैंडलर हालांकि कि सीधे आईडीई का उपयोग कर ऐसा नहीं इस कोड में दिखा किया है जोड़ा है परिभाषा: वस्तु के रूप में निम्नानुसार किया जाता है नीचे!)):

dataGrid.VirtualMode = true; 

_cache = new ResultRowCache(PAGE_SIZE, captureResults); 

dataGrid.Columns.Add("FirstColumn" , "First column header"); 
dataGrid.Columns.Add("Second Column", "Second column header"); 
/* Etc. Adding all columns. (Every member or ResultRow has it's own column. */ 

dataGrid.RowCount = (int)_cache.TotalCount; 

एक बात मैं सोच रहा हूं कि रोकाउंट कैसे शुरू किया गया है। यह शायद 0 है (ResultRowCache के कन्स्ट्रक्टर कॉल के कारण (नीचे देखें)) लेकिन ऐसा कभी नहीं बदला जाता है। क्या यह असाइनमेंट संदर्भ के रूप में गिना जाता है? खुद को कैसे लागू करता है?

void DataGridCellValueNeededEvent(object sender, DataGridViewCellValueEventArgs e) 
{ 
    _cache.LoadPage(e.RowIndex); 

    int rowIndex = e.RowIndex % _cache.PageSize; 

    switch (dataGrid.Columns[e.ColumnIndex].Name) 
    { 
     /* Not actual names, example */ 
    case "FirstColumn": e.Value = _cache.CachedData[rowIndex].First; break; 
     case "SecondColumn": e.Value = _cache.CachedData[rowIndex].Second; break; 
     /* Rest of the possibly columns/ResultRow values */ 
    } 
} 

समस्या:

public class ResultRowCache 
{ 
    public int PageSize = 100; 
    public long TotalCount; 
    public List<ResultRow> CachedData = null; 
    private List<ResultRow> FullData; 

    int _lastRowIndex = -1; 

    public ResultRowCache (int pageSize, List<ResultRow> total) 
    { 
     PageSize = pageSize; 
     FullData = total; 

     LoadPage(0); 
    } 

    public void LoadPage (int rowIndex) 
    { 
     int lastRowIndex = rowIndex - (rowIndex % PageSize); 

     /* Page already loaded */ 
     if(lastRowIndex == _lastRowIndex) return; 

     /* New page */ 
     _lastRowIndex = lastRowIndex; 

     /* Create a new cashes data object */ 
     if(CachedData == null) CachedData = new List<ResultRow>(); 

     /* If cached data already existed, clear */ 
     CachedData.Clear(); 

     /* The index is valid (there is data */ 
     if (lastRowIndex < FullData.Count) 
     { 
      /* Not a full page */ 
      if (lastRowIndex + PageSize > FullData.Count) 
      { 
       CachedData = FullData.GetRange(lastRowIndex, ((lastRowIndex + PageSize) - 1) - FullData.Count); 

      } 
      /* Full page */ 
      else 
      { 
       CachedData = FullData.GetRange(lastRowIndex, PageSize); 
      } 
     } 

     TotalCount = CachedData.Count; 
    } 
    } 
} 

अन्त में, datagrid के लिए मेरे CellValueNeeded घटना इस प्रकार परिभाषित किया गया है:

वैसे भी, मैं क्या है के साथ आगे, ResultRowCache इस प्रकार परिभाषित किया गया है मेरे "कैप्चर रिसेट्स" सूची भरने के बावजूद डाटाग्रिड खाली रहता है। यहां मैंने अभी तक कोशिश की है:

  • ईवेंट में स्विच के बाद डेटाग्रिड के रोकाउंट सदस्य को अपडेट करें।
  • यह सुनिश्चित करने के लिए कि यह हमेशा अद्यतित है, कैश के भीतर परिणामों की कुल मात्रा के साथ सूची घोषित करें। (मुझे डर था कि "संशोधनों के बाहर" कैश किए गए कन्स्ट्रक्टर में पारित सूची में नहीं जायेगा, भले ही यह एक संदर्भ था। (सी # के साथ बिल्कुल नया))
  • डेटाग्रिड की पंक्ति गणना 100 तक (हार्ड वैल्यू) फॉर्म के लोड इवेंट में।
  • कैप्चर रेसल्ट सूची में कुछ जोड़ने के बाद डेटाग्रिड को "अपडेट()" कॉल जोड़ा गया। (यह एक विशेष थ्रेड से होता है जो Invoke का एक फ़ंक्शन जो सूची में कुछ जोड़ता है)

उपर्युक्त में से कोई भी कुछ भी नहीं बदला। ग्रिड खाली रहता है। मुझे लगता है कि मैं यहां कुछ स्पष्ट याद कर रहा हूं। कोई सुझाव?

-edit- कुछ ऐसा जोड़ा जो मैंने इसे काम करने की कोशिश की।

उत्तर

2

मुझे लगता है कि कैश के उपयोग की प्रक्रिया उलझी है कुछ हद तक (हालांकि मैं तुम्हें MSDN एक जो इस फैशन में लागू करता है के लिए लिंक भेजने के बाद जिम्मेदार महसूस करते हैं)।

क्या मैं एक प्रारंभिक बिंदु के रूप में की सिफारिश करेंगे है:

  1. फेंक दूर कैश (यह उपयोगी हो सकता है बाद में अगर आप स्मृति समस्याओं में चलाने, लेकिन अब के लिए बस अपने datagrid populating प्राप्त करने देता है)

  2. एक उदाहरण चर में अपने List<ResultsRow> स्टोर करें।

  3. सुनिश्चित करें कि dataGrid.VirtualMode = true; (या समकक्ष)

  4. लागू CellValueNeeded इस प्रकार है:

    private void gridContacts_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) 
        { 
         ResultRow dataObject = resultRows[e.RowIndex]; 
    
         switch(e.ColumnIndex) 
         { 
          case 0: 
           e.Value = dataObject.First; 
           break; 
          case 1 : 
           e.Value = dataObject.Second; 
           break; 
          //etc.. 
         } 
        } 
    

नोट: यदि आप DataObject में कुछ अतिरिक्त सार्वजनिक संपत्तियों को बेनकाब करने के लिए इतना है कि वे हो सकता है की आवश्यकता होगी विधि में मान के रूप में सेट करें।

कैसे आप उस के साथ पर मिलता है देखें। यदि आप CellValueNeeded विधि के भीतर कुछ ब्रेकपॉइंट सेट करते हैं जो किसी और अप्रत्याशित व्यवहार को डिबग करने में मदद करनी चाहिए। सौभाग्य।

+0

मैं इसे अपने सूची के आकार के साथ हर अलावा के बाद ROWCOUNT अपडेट करके (कैश) के बिना काम कर पाने में कामयाब रहे। हालांकि प्रदर्शन खराब दिखता है। (हो सकता है क्योंकि मैं पृष्ठभूमि कार्यकर्ता द्वारा प्रत्येक एमएस के बजाय हर अतिरिक्त फॉर्म को अपडेट कर रहा हूं) मेरा एप्लिकेशन डेटा प्रोसेस करने के बाद अपेक्षाकृत तेज़ी से जमा हो जाता है। क्या यह वर्चुअल मोड का गलत कार्यान्वयन है या क्या समस्या कहीं और झूठ बोलती है? (कुछ पंक्तियों ड्राइंग कारण के लिए (जो अलग-अलग पृष्ठभूमि रंग कैसे आ आप प्रत्येक इसके बाद ROWCOUNT अद्यतन कर रहे हैं हो सकता है) इस प्रणाली के लिए बहुत मुश्किल है। मेरे लैपटॉप (जो अधिक शक्तिशाली है) यह और अधिक आसानी से कर सकते हैं। – Arnold4107176

+0

? सकते हैं आप इस कोड को साझा करते हैं, के रूप में मुझे यकीन है कि कैसे काम करता है, और बहुत सही नहीं लग रहा नहीं कर रहा हूँ। यदि आप एक bindingSource है, जो तब तो rowCounts Grid.DataSource को सौंपा गया है और आंतरिक सूचियों पर्याप्त नज़र रखी जानी चाहिए करने के लिए अपने सूची असाइन करते हैं। –

+0

आह, मुझे लगता है कि इस अवधारणा के बारे में समझ की मेरी कमी का परिणाम है। मैं अपने DataGridView जब मैं आभासी मोड सक्षम के रूप में मैं मान लिया है इस प्रदर्शन समस्या थी के लिए एक डेटा स्रोत निर्धारित नहीं की। अगर मैं रखें कि चातुर्य फर्क सिर्फ इतना में यह है कि मैंने वर्चुअलमोड प्रॉपर्टी को सत्य पर सेट किया है, और सेलवैल्यूइडेड इवेंट को परिभाषित किया है। क्या यह सही है? मुझे समझ में नहीं आता कि यह प्रदर्शन प्रदर्शन क्यों करता है जो आपको अन्यथा मिल जाएगा। क्या मैं बड़े सेट के लिए इतनी अक्षम है कि घटना के डिफ़ॉल्ट कार्यान्वयन टी? आभासी मोड के साथ इसे ओवरराइड करना शायद काम नहीं करेगा, मुझे पढ़ना होगा। – Arnold4107176

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