2
votes

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!

1

1 Answers

4
votes

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