Reputation: 1016
I have a list of DownloadOperation in ObservableCollection and the variable has the property Progress.TotalBytesToReceive & Progress.BytesReceived. When i tried to bind this property to max & value of progress bar it gives me binding expression error property does not found. I bind other property ResultFile.Name and it success. Is there any possible way to fix this?
UPDATE :
I found that I need to use converter from progress to get the totalbytes value, but the problem now the value is not updated, and seems like observablecollection does not watch the bytes received value.
<ListView DataContext="{Binding Download}"
ItemsSource="{Binding}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Margin="5">
<TextBlock Text="{Binding ResultFile.Name}"
FontSize="20"
Foreground="Black"/>
<ProgressBar Maximum="100"
Value="{Binding Progress, Converter={StaticResource ByteReceivedConverter}}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I have this as viewmodel, the activeDownloads contains list of observable download.
public ObservableCollection<DownloadOperation> activeDownloads = new ObservableCollection<DownloadOperation>();
And I tried to extract the BytesReceived & TotalBytesToReceive in code behind
double received = 0;
double total = 0;
foreach (var item in activeDownloads)
{
received += item.Progress.BytesReceived;
total += item.Progress.TotalBytesToReceive;
}
if (total != 0) {
var percentage = received / total * 100;
It works without any problem, The observablecollection also works fine, when I add download it automatically change the view without I have to update the datacontext manually, same result if the download finish/removed. But if I directly bind the Progress.BytesReceived to the progressbar Value it gives me Path Error, but I am able to bind it to Progress property. So I make a converter to retrieve the value.
Here is Convereter I use to convert the Progress property :
public class ByteReceivedConverter:IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
BackgroundDownloadProgress bytes = (BackgroundDownloadProgress)value;
if (bytes.TotalBytesToReceive != 0)
return bytes.BytesReceived/bytes.TotalBytesToReceive*100;
else return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
And is it possible to make this DownloadOperation has observability to the bytesreceived level?, since I did not make this property, I just retrieve it from meta. Or am I doing it wrong? because for now the problem i got is the view does not aware that the bytesreceived value is change.
If it's not possible should I make another viewmodel with INotifyPropertyChanged implemented?
Upvotes: 0
Views: 128
Reputation: 10744
First of all, you don't need to use a converter; binding the Max and Value properties would have been fine, but you probably didn't make the source values as public properties or you had the Path set incorrectly in the binding.
With the way you are doing it now, you will need to raise the property changed event of INotifyPropertyChanged for the Progress property each time BytesReceived is updated, because that is the property that you are binding to.
Upvotes: 1