2011-08-31 12 views
5

के साथ लिस्टबॉक्स में अगले लॉजिकल पेज पर स्क्रॉल कैसे करें मेरे पास एक सूची बॉक्स है जिसमें CanContentScroll == false होना चाहिए क्योंकि मुझे इसे आसानी से स्क्रॉल करने में सक्षम होना चाहिए। यह भौतिक स्क्रॉलिंग को सक्षम बनाता है।भौतिक स्क्रॉलिंग

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

मैं चाहता हूं कि पहली पंक्ति हमेशा पूरी तरह दिखाई दे, जैसे तार्किक स्क्रॉलिंग का उपयोग करते समय।

क्या कोई मुझे ऐसा करने के बारे में संकेत दे सकता है?

उत्तर

2

यदि आप नीचे स्क्रॉल और फिर माउस के साथ ऊपरी दिखाई कंटेनर का चयन एक virtualizing एक के लिए के रूप में एक गैर virtualizing ItemsControl (ScrollViewer.CanContentScroll="False") के लिए एक ही प्रभाव मिल जाएगा। यह कोड में भी किया जा सकता है।

जब CanContentScroll झूठी पर सेट है, वर्चुअलाइजिंग बंद है इसलिए सभी कंटेनर हर समय उत्पन्न होंगे। शीर्ष दृश्य कंटेनर प्राप्त करने के लिए हम ScrollViewer के VerticalOffset तक पहुंचने तक शीर्ष से कंटेनरों को फिर से सक्रिय कर सकते हैं। एक बार जब हम इसे प्राप्त कर लेंगे तो हम इसे BringIntoView पर कॉल कर सकते हैं और यह शीर्ष पर अच्छी तरह से संरेखित होगा जैसे वर्चुअलाइजेशन का उपयोग किया जा रहा था।

उदाहरण

<ListBox ItemsSource="{Binding MyCollection}" 
     ScrollViewer.CanContentScroll="False" 
     ScrollViewer.ScrollChanged="listBox_ScrollChanged" > 

ईवेंट हैंडलर में शीर्ष दिखाई कंटेनर पर कॉल BringIntoView

private void listBox_ScrollChanged(object sender, ScrollChangedEventArgs e) 
{ 
    ItemsControl itemsControl = sender as ItemsControl; 
    ScrollViewer scrollViewer = e.OriginalSource as ScrollViewer; 
    FrameworkElement lastElement = null; 
    foreach (object obj in itemsControl.Items) 
    { 
     FrameworkElement element = itemsControl.ItemContainerGenerator.ContainerFromItem(obj) as FrameworkElement; 
     double offset = element.TransformToAncestor(scrollViewer).Transform(new Point(0, 0)).Y + scrollViewer.VerticalOffset; 
     if (offset > e.VerticalOffset) 
     { 
      if (lastElement != null) 
       lastElement.BringIntoView(); 
      break; 
     } 
     lastElement = element; 
    } 
} 

करने के लिए केवल इस प्रभाव को प्राप्त जब आप PageDown कॉल करना चाहते हैं में, उदाहरण के लिए एक बटन क्लिक करें, आप मुझे एक एक्सटेंशन बना सकते हैं ListBox के लिए थोड LogicalPageDown कहा जाता है।

listBox.LogicalPageDown(); 

ListBoxExtensions

public static class ListBoxExtensions 
{ 
    public static void LogicalPageDown(this ListBox listBox) 
    { 
     ScrollViewer scrollViewer = VisualTreeHelpers.GetVisualChild<ScrollViewer>(listBox); 
     ScrollChangedEventHandler scrollChangedHandler = null; 
     scrollChangedHandler = (object sender2, ScrollChangedEventArgs e2) => 
     { 
      scrollViewer.ScrollChanged -= scrollChangedHandler; 
      FrameworkElement lastElement = null; 
      foreach (object obj in listBox.Items) 
      { 
       FrameworkElement element = listBox.ItemContainerGenerator.ContainerFromItem(obj) as FrameworkElement; 
       double offset = element.TransformToAncestor(scrollViewer).Transform(new Point(0, 0)).Y + scrollViewer.VerticalOffset; 
       if (offset > scrollViewer.VerticalOffset) 
       { 
        if (lastElement != null) 
         lastElement.BringIntoView(); 
        break; 
       } 
       lastElement = element; 
      } 
     }; 
     scrollViewer.ScrollChanged += scrollChangedHandler; 
     scrollViewer.PageDown(); 
    } 
} 

मैं अपने प्रश्न है कि आप पहले से ही ScrollViewer मिला में देखा है, लेकिन मैं GetVisualChild के एक कार्यान्वयन जोड़ रहा किसी और को इस सवाल का

public static T GetVisualChild<T>(DependencyObject parent) where T : Visual 
{ 
    T child = default(T); 

    int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
    for (int i = 0; i < numVisuals; i++) 
    { 
     Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
     child = v as T; 
     if (child == null) 
     { 
      child = GetVisualChild<T>(v); 
     } 
     if (child != null) 
     { 
      break; 
     } 
    } 
    return child; 
} 
+0

@Zmaster: भूल गए कि 'मार्जिन' इत्यादि कंटेनर की सापेक्ष स्थिति ढूंढते समय शामिल हो सकते हैं। –

+0

के अनुसार मेरा उत्तर अपडेट किया गया अंत में मैंने लक्ष्य ऑफसेट की गणना करके स्क्रॉलटॉऑफसेट() का उपयोग करने का निर्णय लिया कि प्रत्येक आइटम की ऊंचाई समान है (यह मेरा मामला है)। यह वस्तुओं को फिर से शुरू करने से अधिक कुशल है। दूसरी तरफ आपका समाधान विभिन्न वस्तुओं की ऊंचाई पर भी काम करता है, इसलिए मैंने इसे उत्तर के रूप में स्वीकार कर लिया। – Zmaster

0

यदि आप "नए पृष्ठ" के शीर्ष आइटम को देखने के लिए स्क्रॉल करते हैं, तो क्या आप जो खोज रहे हैं वह प्राप्त करेंगे? ScrollIntoView देखें।

+0

भर आता है, तो मुझे लगता है कि आइटम शीर्ष के बजाय सूची बॉक्स पर नीचे दिखाई देगा। साथ ही, मुझे नहीं पता कि उस आइटम को कैसे पहचानें। – Zmaster

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

  • कोई संबंधित समस्या नहीं^_^