افتراضية العناصر المستحقة؟
-
03-10-2019 - |
سؤال
انا لدي 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
لكن هذا لا يبدو أنه يساعد.
المحلول
هناك في الواقع أكثر بكثير من مجرد صنع ItemsPanelTemplate
استعمال VirtualizingStackPanel
. الافتراضي ControlTemplate
إلى عن على ItemsControl
ليس لديه ملف ScrollViewer
, ، وهو مفتاح المحاكاة الافتراضية. إضافة إلى قالب التحكم الافتراضي ل ItemsControl
(باستخدام قالب التحكم لـ ListBox
كقالب) يعطينا ما يلي:
<ItemsControl
VirtualizingStackPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True"
ItemsSource="{Binding Path=AccountViews.Tables[0]}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock
Initialized="TextBlock_Initialized"
Text="{Binding Path=Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<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>
</ItemsControl.Template>
</ItemsControl>
(راجع للشغل ، أداة رائعة للنظر في قوالب التحكم الافتراضية أرني القالب)
أشياء يجب ملاحظتها:
عليك تعيين ScrollViewer.CanContentScroll="True"
, ، نرى هنا لماذا.
لاحظ أيضًا أنني وضعت VirtualizingStackPanel.VirtualizationMode="Recycling"
. هذا سوف يقلل من أعداد الأوقات TextBlock_Initialized
يتم استدعاؤه إلى العديد من أنواع النصوص المرئية على الشاشة. يمكنك قراءة المزيد على واجهة المستخدم الافتراضية هنا.
تحرير: نسيت أن تذكر ما هو واضح: كحل بديل ، يمكنك فقط استبدال ItemsControl
مع ListBox
:) أيضا ، تحقق من هذا تحسين الأداء على صفحة MSDN ولاحظ ذلك ItemsControl
ليس في جدول "عناصر التحكم التي تنفذ ميزات الأداء" ، وهذا هو السبب في أننا نحتاج إلى تحرير قالب التحكم.
نصائح أخرى
بناءً على إجابة Davidn ، إليك نمط يمكنك استخدامه على العناصر الشهرية لإظهاره:
<!--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>
لا أحب الاقتراح لاستخدام صندوق القائمة لأنها تسمح باختيار الصفوف التي لا تريدها بالضرورة.
إنه مجرد الافتراضي ItemsPanel
ليس أ VirtualizingStackPanel
. تحتاج إلى تغييره:
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>