2013-01-11 11 views
12

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

सूची बॉक्स 'आइटम पैनल तब मेरे कस्टम वर्चुअलाइज्ड कैनवास के रूप में सेट किया गया है।

समस्या मैं का सामना कर रहा हूँ इस परिदृश्य में होता है:

  • ListBox आइटम एक पहले बनाया जाता है।
  • सूची बॉक्स आइटम बी कैनवास पर आइटम ए के दाईं ओर बनाया गया है।
  • लिस्टबॉक्स आइटम ए पहले वर्चुअलाइज्ड है (इसे देखने से बाहर पैन करके)।
  • लिस्टबॉक्स आइटम बी वर्चुअलाइज्ड दूसरा है (फिर इसे देखने से बाहर पैन करके)।
  • ध्यान में रखते हुए ListBox आइटम ए और बी लाओ (यानी: उन्हें एहसास)
  • स्नूप का उपयोग करना, मैं पता लगाने कि ListBox अब 3 आइटम, उनमें से एक एक "DisconnectedItem" नीचे ListBox आइटम बी सीधे स्थित किया जा रहा है

इस "डिस्कनेक्ट किए गए इटिम" के निर्माण का कारण क्या है? अगर मैं पहले बी को वर्चुअलाइज करना चाहता था, तो ए के बाद, यह आइटम नहीं बनाया जाएगा। मेरा सिद्धांत यह है कि लिस्टबॉक्स में अन्य वस्तुओं से पहले वर्चुअलाइजिंग आइटम बच्चों को डिस्कनेक्ट करने का कारण बनता है।

समस्या सैकड़ों नोड्स के साथ ग्राफ का उपयोग करके और भी स्पष्ट है, क्योंकि मैं सैकड़ों डिस्कनेक्ट किए गए आइटमों के साथ समाप्त होता हूं क्योंकि मैं घूमता हूं।

यहाँ कैनवास के लिए कोड का एक हिस्सा है:

/// <summary> 
/// Arranges and virtualizes child element positionned explicitly. 
/// </summary> 
public class VirtualizingCanvas : VirtualizingPanel 
{ 
    (...) 

    protected override Size MeasureOverride(Size constraint) 
    { 
     ItemsControl itemsOwner = ItemsControl.GetItemsOwner(this); 

     // For some reason you have to "touch" the children collection in 
     // order for the ItemContainerGenerator to initialize properly. 
     var necessaryChidrenTouch = Children; 

     IItemContainerGenerator generator = ItemContainerGenerator; 

     IDisposable generationAction = null; 

     int index = 0; 
     Rect visibilityRect = new Rect(
      -HorizontalOffset/ZoomFactor, 
      -VerticalOffset/ZoomFactor, 
      ActualWidth/ZoomFactor, 
      ActualHeight/ZoomFactor); 

     // Loop thru the list of items and generate their container 
     // if they are included in the current visible view. 
     foreach (object item in itemsOwner.Items) 
     { 
      var virtualizedItem = item as IVirtualizingCanvasItem; 

      if (virtualizedItem == null || 
       visibilityRect.IntersectsWith(GetBounds(virtualizedItem))) 
      { 
       if (generationAction == null) 
       { 
        GeneratorPosition startPosition = 
           generator.GeneratorPositionFromIndex(index); 
        generationAction = generator.StartAt(startPosition, 
              GeneratorDirection.Forward, true); 
       } 

       GenerateItem(index); 
      } 
      else 
      { 
       GeneratorPosition itemPosition = 
           generator.GeneratorPositionFromIndex(index); 

       if (itemPosition.Index != -1 && itemPosition.Offset == 0) 
       { 
        RemoveInternalChildRange(index, 1); 
        generator.Remove(itemPosition, 1); 
       } 

       // The generator needs to be "reseted" when we skip some items 
       // in the sequence... 
       if (generationAction != null) 
       { 
        generationAction.Dispose(); 
        generationAction = null; 
       } 
      } 

      ++index; 
     } 

     if (generationAction != null) 
     { 
      generationAction.Dispose(); 
     } 

     return default(Size); 
    } 

    (...) 

    private void GenerateItem(int index) 
    { 
     bool newlyRealized; 
     var element = 
      ItemContainerGenerator.GenerateNext(out newlyRealized) as UIElement; 

     if (newlyRealized) 
     { 
      if (index >= InternalChildren.Count) 
      { 
       AddInternalChild(element); 
      } 
      else 
      { 
       InsertInternalChild(index, element); 
      } 

      ItemContainerGenerator.PrepareItemContainer(element); 

      element.RenderTransform = _scaleTransform; 
     } 

     element.Measure(new Size(double.PositiveInfinity, 
           double.PositiveInfinity)); 
    } 
+0

क्या आप कंटेनर रीसाइक्लिंग कर रहे हैं? – Paparazzi

+0

@ बलाम: मुझे नहीं लगता कि मैं हूं, कंटेनर रीसाइक्लिंग करके आपका क्या मतलब है? –

+0

बस रीसायकल कंटेनर के लिए msdn खोजें http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizationmode.aspx बस एक पहुंच लेकिन केवल एक टिप्पणी – Paparazzi

उत्तर

7

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

इस WPF 4

में एक ज्ञात बग this link for known bug देखें, यह भी एक वैकल्पिक हल आप लागू करने में सक्षम हो सकता है किया गया है।

संपादित करें:।

"आप प्रहरी वस्तु {DisconnectedItem} पहली बार जब आप यह देखने के लिए एक संदर्भ की बचत है, तो उस के बाद बचा लिया मूल्य के खिलाफ की तुलना करके अपने समाधान एक छोटे से अधिक मजबूत बना सकते हैं

हमें {DisconnectedItem} के परीक्षण के लिए एक सार्वजनिक तरीका बनाना चाहिए था, लेकिन यह दरारों के माध्यम से फिसल गया। हम इसे भविष्य में रिलीज में ठीक कर देंगे, लेकिन अभी आप इस तथ्य पर भरोसा कर सकते हैं कि एक अद्वितीय {डिस्कनेक्टेड इटैम} ऑब्जेक्ट है। "

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