Usually I use ListBox to list the item,s but if we load 1000 records (items) at a time may reduce the performance and consume more memory.
ListBox offers UI virtualization that means loading items on demand to increase the performance.
Data Virtualization
Data virtualization is the concept of only loading “enough” data to fill out your UI and use it. A Stack Virtualization Stack panel manages the viewport by ordering the visual items in a stack layout. Items at the top and bottom edges of the stack are recycled to be further reused depending on the direction of scrolling.
Create new windows phone 8 project and add the ListBox control in your MainPage.xaml.
Now design the page as in the following XAML code.
XAML Code
- <!--ContentPanel - place additional content here-->
- <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
- <ListBox x:Name="listbox" ItemsSource="{Binding}" >
- <ListBox.ItemsPanel>
- <ItemsPanelTemplate>
- <VirtualizingStackPanel VirtualizingStackPanel.VirtualizationMode="Recycling"/>
- </ItemsPanelTemplate>
- </ListBox.ItemsPanel>
- <ListBox.ItemTemplate>
- <DataTemplate>
- <StackPanel>
- <Image Source="{Binding Photo}" Width="50" Height="50"/>
- <TextBlock Text="{Binding Name}" Foreground="Wheat" FontSize="25" TextWrapping="Wrap" Width="166"/>
- </StackPanel>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
- </Grid>
Set VirtualizingStackPanel VirtualizationMode property for recycling to virtualize the UI.
I am going to load some random images and text in the list, so I am writing the following code to perform the task.
C# Code- ObservableCollection < Chapters > NewsList = new ObservableCollection < Chapters > ();
- Random random = new Random();
- static long totlaBytes;
- static long currentBytes;
- static long peakBytes;
-
- public MainPage()
- {
- InitializeComponent();
-
-
- }
- private void PhoneApplicationPage_Loaded_1(object sender, RoutedEventArgs e) {
- LoadNews(250);
- this.DataContext = NewsList;
- CheckMemory();
- }
- void LoadNews(int Length)
- {
- for (int i = 0; i < Length; i++)
- {
- NewsList.Add(new Chapters
- {
- Name = "C# Corner Chapter " + random.Next(1, 22),
- Photo = "Assets/Images/" + random.Next(0, 3) + ".png"
-
- });
- };
- }
- public class Chapters: System.ComponentModel.INotifyPropertyChanged
- {
- string name;
- public string Name
- {
- get
- {
- return name;
- }
- set
- {
- if (value != name)
- {
- name = value;
- NotifyPropertyChanged("Name");
- }
- }
- }
- string photo;
- public string Photo
- {
- get
- {
- return photo;
- }
- set
- {
- if (value != photo)
- {
- photo = value;
- NotifyPropertyChanged("Photo");
- }
- }
- }
- public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
- public void NotifyPropertyChanged(string propertyName)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
- }
- }
- }
-
- static System.Windows.Threading.DispatcherTimer dispacherTimer;
- void CheckMemory() {
- dispacherTimer = new System.Windows.Threading.DispatcherTimer();
- dispacherTimer.Interval = TimeSpan.FromSeconds(1);
- dispacherTimer.Tick += new EventHandler(dispacherTimer_Tick);
- dispacherTimer.Start();
- }
- void dispacherTimer_Tick(object sender, EventArgs e)
- {
- totlaBytes = (long) Microsoft.Phone.Info.DeviceExtendedProperties.GetValue("DeviceTotalMemory");
- currentBytes = (long) Microsoft.Phone.Info.DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage");
- peakBytes = (long) Microsoft.Phone.Info.DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage");
- memory.Text = string.Format("Current:{0:F2}MB; Peak:{1:F2}MB; Total:{2:F2}MB", currentBytes / (1024 * 1024.0), peakBytes / (1024 * 1024.0), totlaBytes / (1024 * 1024.0));
- }
- }
Now see the output to optimise the memory usage and performance.
Figure 1: Output