{"id":2676,"date":"2014-12-05T21:04:10","date_gmt":"2014-12-05T21:04:10","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=2676"},"modified":"2014-12-05T21:04:10","modified_gmt":"2014-12-05T21:04:10","slug":"wpf-controls-and-virtualization","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/wpf-controls-and-virtualization\/","title":{"rendered":"WPF Controls and Virtualization"},"content":{"rendered":"<p>Some of the built-in WPF control can be virtualized and some <strong>are<\/strong> virtualized by default. See <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/cc716879%28v=vs.110%29.aspx\" title=\"Optimizing Performance: Controls\" target=\"_blank\">Optimizing Performance: Controls<\/a>.<\/p>\n<p>I&#8217;m working on migrating a WinForm application to WPF, in doing so I happily recreated the code to load a ComboBox with a fairly large amount of data from a web service call. In the Windows Forms ComboBox this seemed to be have fairly good performance. Not so in the WPF ComboBox! <\/p>\n<p>Some WPF controls, such as the ComboBox create their list control\/dropdown to accommodate all items, therefore all items are rendered to the popup associated with it. It then uses a ScrollViewer to handle the scrolling of this large view object. Obviously when we&#8217;re talking about something like 10,000+ items (as I&#8217;m populating it with), clicking the dropdown button results in a very slow display of the associated popup whilst it&#8217;s busy rendering non-visible items.<\/p>\n<p>What would be preferably is if we could load only the items to fit the dropdown space into the popup and have the scrollbar &#8220;think&#8221; that there&#8217;s more data, then we can &#8220;virtualize&#8221; our loading of data into the UI control.<\/p>\n<p>We do this using the following code<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;ComboBox ItemsSource=&quot;{Binding}&quot;&gt;\r\n   &lt;ComboBox.ItemsPanel&gt;\r\n      &lt;ItemsPanelTemplate&gt;\r\n         &lt;VirtualizingStackPanel \/&gt;\r\n      &lt;\/ItemsPanelTemplate&gt;\r\n   &lt;\/ComboBox.ItemsPanel&gt;\r\n&lt;\/ComboBox&gt;\r\n<\/pre>\n<p><strong>Other ItemsControl objects<\/strong><\/p>\n<p>In the case of the WPF ListView and ListBox, both are virtualized by default. <\/p>\n<p>However, to paraphrase <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/cc716879%28v=vs.110%29.aspx\" title=\"Optimizing Performance: Controls\" target=\"_blank\">&#8220;Optimizing Performance: Controls&#8221;<\/a><\/p>\n<p><em>By default WPF ListBoxes use UI virtualization when used with databinding, however if you add ListBoxItem&#8217;s explicitly the ListBox does not virtualize.<\/em><\/p>\n<p>The TreeView can be enabled using the following code<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;TreeView ItemsSource={Binding} VirtualizingStackPanel.IsVirtualizing=&quot;True&quot; \/&gt;\r\n<\/pre>\n<p>The ContextMenu can also be virtualized.<\/p>\n<p><strong>Scrolling<\/strong><\/p>\n<p>We might find that an ItemsControl, for example a ListBox, is slow when scrolling. In this case we can use the attached property VirtualizingStackPanel.VirtualizationMode as per<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;ListBox ItemsSource={Binding} VirtualizingStackPanel.VirtualizationMode=&quot;Recycling&quot; \/&gt;\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Some of the built-in WPF control can be virtualized and some are virtualized by default. See Optimizing Performance: Controls. I&#8217;m working on migrating a WinForm application to WPF, in doing so I happily recreated the code to load a ComboBox with a fairly large amount of data from a web service call. In the Windows [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[13],"tags":[],"class_list":["post-2676","post","type-post","status-publish","format-standard","hentry","category-wpf"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2676","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=2676"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2676\/revisions"}],"predecessor-version":[{"id":2693,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2676\/revisions\/2693"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=2676"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=2676"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=2676"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}