Many times, our interface presents a large amount of data, such as a table with thousands of records or an album with hundreds of photos. Because rendering the UI is a relatively expensive action, rendering hundreds of photos at once is a lot of memory and time for the current computer performance. Therefore, it needs to be optimized. Most of the previous scenarios were page-flipping, which caused a disruption to users ' browsing in some way, so a new scenario--ui virtualization is now often used.
The principle of UI virtualization is: but because of the limitations of the monitor and the human eye, the user will see only dozens of of the data at the same time, so as long as the interface to render the user's view of the data can be, the user presents the interface is still the same. Microsoft's MSDN document UI virtualization instructions are more detailed, and this is not the case.
On the implementation of UI virtualization, the core is Virtualpanel, in WPF built-in Virtualpanel seems to only virtualizingstackpanel one, but this is also the most practical, commonly used in tables and other data rendering. If you need a panel with a different layout, you'll need to implement it yourself, and a series of articles on MSDN blog are more detailed:
- Implementing a Virtualizingpanel part I
- Implementing a Virtualizingpanel part II
- Implementing a Virtualizingpanel part III
- Implementing a Virtualizingpanel part IV
At the end of the article comes a virtualizingtilepanel that implements a similar wrappanel effect (it requires that the element size is equal). For photo browsing and the like to continue or relatively convenient, do not know why m$ official did not bring this. The original. NET version is older, is directly compiled not past, need to modify it yourself.
Implementing a custom Virtualizingpanel is not very complex, first introduces several preconditions:
1. Virtualizingpanel is used for UI virtualization, it is used to do ItemsControl ItemTemplate, rather than the direct control of children like a normal panel. Therefore, it must be used in conjunction with ItemsControl and its subclasses (such as the DataGrid, ListBox) and inherit from Virtualizingpanel.
2. Virtualizingpanel is required to be used with ScrollViewer, without scrolviewer, all controls are visible, not virtualized. Note that the default template for ItemsControl is not scrollviewer, and you need to modify the template when using Virtualizingpanel in ItemsControl. Add ScrollViewer, and set cancontentscroll= "True".
3. UI virtualization requires that the elements in the current view be rendered without rendering all the UI controls, and that if all the data is converted to a control, it is not virtualized. In other words, the layout cannot be determined by measure and arrange all child elements.
The specific implementation of the time generally have the following several function points:
- The panel needs to implement the IScrollInfo interface so that it can manually control the interface virtualization at the time of scrolling. About the IScrollInfo interface, I have some introduction in the previous article, you can refer to.
- The panel needs to be able to only perceive the overall layout based on data. There are three kinds of common scenarios: 1. Specify the amount of space occupied by each child element directly in the panel, 2. Take the size of the first child element to measure the size of the other sub-elements, 3. Directly declare the size that it needs in the data
- The panel renders the element based on the size of the current window (the visible element is loaded, and the invisible element is removed).
Examples can be directly referred to the previous one, here is not a separate example.
Data virtualization:
UI virtualization solves the problem of having more time and memory to render UI controls, but there is still room for optimization, and that is all the data is still loaded into memory. We can still adopt the same optimization scheme as UI virtualization: not loading all the data into the collection, loading only the visible parts of the user. Data virtualization itself is not supported by WPF, but when our panel implements the IScrollInfo interface, it is possible to sense the scroll bar precisely, and it is not difficult to achieve data virtualization.
In general, we rarely use data virtualization, the main reason is that most of the time it can only reduce a little bit of memory footprint, but instead brings a large code complexity, is generally considered worth the candle.
However, sometimes, our data comes from external RPC access, this time data virtualization is meaningful, consider the following two scenarios:
- News client, the data source is from the remote Rest service, but its interface is paged get, can only get 50 each time, total may have 100 pages.
- Picture browser, the picture is not from the local, but from the Image service website.
The first example is a more typical application scenario for data virtualization, and it can take a lot of time to load all 100 pages of news from the beginning. The second example is part of the data virtualization, the picture information does not need to be virtualized, but the picture needs to be virtualized, but only when it needs to be presented to download from the network.
UI virtualization for WPF