एक ItemControl वर्चुअलाइजेशन?


125

मेरे पास ItemsControlडेटा की एक सूची है, जिसे मैं वर्चुअलाइज करना चाहूंगा, हालांकि ए के VirtualizingStackPanel.IsVirtualizing="True"साथ काम करना संभव नहीं लगता ItemsControl

क्या यह वास्तव में ऐसा है या ऐसा करने का एक और तरीका है जिसके बारे में मुझे जानकारी नहीं है?

परीक्षण के लिए मैं कोड के निम्नलिखित ब्लॉक का उपयोग कर रहा हूं:

<ItemsControl ItemsSource="{Binding Path=AccountViews.Tables[0]}"
              VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <TextBlock Initialized="TextBlock_Initialized"  
                   Margin="5,50,5,50" Text="{Binding Path=Name}" />
    </DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

अगर मैं बदल ItemsControlएक करने के लिए ListBox, मैं देख सकता है कि Initializedघटना केवल समय की एक मुट्ठी भर चलाता है (बस इसलिए मैं केवल कुछ ही रिकॉर्ड के माध्यम से जाना है विशाल मार्जिन कर रहे हैं), हालांकि के रूप में एक ItemsControlहर आइटम प्रारंभ हो जाता है।

मैं स्थापित करने की कोशिश की है ItemsControlPanelTemplateएक करने के लिए VirtualizingStackPanel, लेकिन वह मदद करने के लिए प्रतीत नहीं होता।

जवाबों:


219

वास्तव में ItemsPanelTemplateइसका उपयोग करने की तुलना में वास्तव में बहुत अधिक है VirtualizingStackPanel। डिफ़ॉल्ट के ControlTemplateलिए ItemsControla नहीं है ScrollViewer, जो वर्चुअलाइजेशन की कुंजी है। के लिए डिफ़ॉल्ट नियंत्रण टेम्पलेट में जोड़ना ItemsControl(टेम्पलेट के ListBoxरूप में नियंत्रण टेम्पलेट का उपयोग करके ) हमें निम्नलिखित देता है:

<ItemsControl ItemsSource="{Binding AccountViews.Tables[0]}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <TextBlock Initialized="TextBlock_Initialized"
                 Text="{Binding Name}" />
    </DataTemplate>
  </ItemsControl.ItemTemplate>

  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <VirtualizingStackPanel IsVirtualizing="True"
                              VirtualizationMode="Recycling" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>

  <ItemsControl.Template>
    <ControlTemplate TargetType="ItemsControl">
      <Border BorderThickness="{TemplateBinding BorderThickness}"
              BorderBrush="{TemplateBinding BorderBrush}"
              Background="{TemplateBinding Background}">
        <ScrollViewer CanContentScroll="True" 
                      Padding="{TemplateBinding Padding}"
                      Focusable="False">
          <ItemsPresenter />
        </ScrollViewer>
      </Border>
    </ControlTemplate>
  </ItemsControl.Template>
</ItemsControl>

(BTW, डिफ़ॉल्ट नियंत्रण टेम्प्लेट को देखने का एक बढ़िया साधन है, Show Me The Template )

ध्यान देने योग्य बातें:

आपको सेट करना है ScrollViewer.CanContentScroll="True", यहां देखें क्यों।

यह भी ध्यान दें कि मैंने डाला VirtualizingStackPanel.VirtualizationMode="Recycling"। यह समय की संख्या को कम करने के लिए TextBlock_Initializedकहा जाता है, हालांकि कई TextBlocks स्क्रीन पर दिखाई देते हैं। आप यूआई वर्चुअलाइजेशन के बारे में अधिक पढ़ सकते हैं यहाँ

EDIT: स्पष्ट रूप से बताना भूल गया: एक वैकल्पिक समाधान के रूप में, आप बस इसके ItemsControlसाथ प्रतिस्थापित कर सकते हैं ListBox:) इसके अलावा, MSDN पृष्ठ पर इस ऑप्टिमाइज़िंग प्रदर्शन की जांच करें और ध्यान दें कि ItemsControl"नियंत्रण लागू कार्यान्वयन सुविधाएँ" तालिका में नहीं है, यही कारण है कि हमें नियंत्रण टेम्पलेट को संपादित करने की आवश्यकता है।


1
धन्यवाद, मैं जिस चीज की तलाश कर रहा था, वह बिल्कुल वैसी ही है! मैं एक सूची बॉक्स की तुलना में एक अलग तरह के चयन व्यवहार की तलाश में था और उस समय मुझे लगा कि आइटम नियंत्रण के साथ ऐसा करना सबसे आसान होगा।
राहेल

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

9
"यह भी ध्यान दें कि मैंने VirtualizingStackPanel.VirtualizationMode = पुनर्चक्रण" रखा। क्या यह आपके द्वारा प्रदान किए गए नमूने में नहीं है?
बकले

वर्चुअलाइजेशन भी काम जब रैप करता है ItemsControlमें ScrollViewerinstread जोड़ने Scrollके लिए ControlTemplate?
डेमो

@ डेविड मैं आपके समाधान में कॉलम हेडर कहां या कैसे डाल सकता हूं?
ओजकान

37

डेविडएन के उत्तर पर निर्माण, यहाँ एक शैली है जिसे आप एक आइटम का उपयोग करके इसे वर्चुअलाइज़ कर सकते हैं:

<!--Virtualised ItemsControl-->
<Style x:Key="ItemsControlVirtualizedStyle" TargetType="ItemsControl">
    <Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ItemsControl">
                <Border
                    BorderThickness="{TemplateBinding Border.BorderThickness}"
                    Padding="{TemplateBinding Control.Padding}"
                    BorderBrush="{TemplateBinding Border.BorderBrush}"
                    Background="{TemplateBinding Panel.Background}"
                    SnapsToDevicePixels="True"
                >
                    <ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

मुझे सूची बॉक्स का उपयोग करने का सुझाव पसंद नहीं है क्योंकि वे उन पंक्तियों के चयन की अनुमति देते हैं जहां आप जरूरी नहीं चाहते हैं।


-3

यह सिर्फ इतना है कि डिफ़ॉल्ट ItemsPanelएक नहीं है VirtualizingStackPanel। आपको इसे बदलने की आवश्यकता है:

<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

8
मैं नीचे मतदान कर रहा हूं क्योंकि समाधान अधूरा है। वर्चुअलाइजेशन को सक्षम करने के लिए आपको टेम्प्लेट में एक स्क्रॉलव्यूअर का उपयोग करने की आवश्यकता है।
सराफ तालुकदार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.