Search code examples
c#xamllistviewwindows-8windows-store-apps

Creating a ListView with updating Progress bar for downloads Windows 8 C# XAML


I am trying to create a ListView that holds a collection of downloads, each with their own progress bar.

The current method I am using is to bind a class that holds the information of currently downloading items, including the current completion percentage of the download:

The item class:

public class DownloadItem
{
    public double downloadPercent { get; set; }
    public string episodeTitle { get; set; }
    public string podcastFeedTitle { get; set; }
    public DownloadOperation operation { get; set; }

    public double percent
    {
        get;
        set;
    }
}

The observableCollection that holds them

public ObservableCollection<DownloadItem> downloadInformationList = new ObservableCollection<DownloadItem>();

The method that's called when progress for the item is changed:

private void DownloadProgress(DownloadOperation download)
{
    double percent = 100;

    if (download.Progress.BytesReceived > 0)
    {
        percent = download.Progress.BytesReceived * 100 / download.Progress.TotalBytesToReceive;
        Debug.WriteLine(percent);
    }

    foreach (DownloadItem item in downloadInformationList)
    {
        if (item.operation == download)
        {
            item.percent = percent;
        }
    }
}

And the XAML code for the itemTemplate for the ListView:

<DataTemplate>
    <StackPanel>
        <TextBlock Text="{Binding episodeTitle, Mode=TwoWay}" />
        <ProgressBar IsIndeterminate="False"
                     Value="{Binding percent, Mode=TwoWay}"
                     Maximum="100"
                     Width="200" />
    </StackPanel>
</DataTemplate>

The ProgressBar works and updates, however it ONLY updates upon returning to the page, not in real-time. What am I doing wrong? Any help would be much appreciated!


Solution

  • Your DownloadItem class needs to implement INotifyPropertyChanged to reflect the real time changes to the Percent property

    public class DownloadItem : INotifyPropertyChanged
    {
        public double downloadPercent { get; set; }
        public string episodeTitle { get; set; }
        public string podcastFeedTitle { get; set; }
        public DownloadOperation operation { get; set; }
    
        private double percent;
        public double Percent
        {
            get { return percent; }
            set
            {
                if (percent == value)
                    return;
    
                percent = value;
                OnPropertyChanged("Percent");
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        public void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    Implementing INotifyPropertyChanged