i'm writing a .NET 4.0 WPF application and i need to load a large image (300 MB) from my hard disk. Loading the image takes a few seconds and i want to show the progress of it by using a progress-bar. I use an image with a BitmapImage as its source. The BitmapImage class provides the DownloadProgress event which is working fine if i load the image from the web. But it does not work if i load the image from my hdd.
Here is the MCVE: The xaml file:
<Window x:Class="progressbar.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:progressbar"
Title="MainWindow" Height="Auto" Width="Auto">
<Window.DataContext>
<local:MainVM />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="250"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Source="{Binding BitmapImg}" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"/>
<TextBox Text="{Binding Url, Mode=TwoWay}" Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1"/>
<Button Content="Load local image file" Grid.Column="0" Grid.Row="2" Click="Button_Click"/>
<Button Content="Load from url" Grid.Column="1" Grid.Row="2" Click="Button_Click_1"/>
<ProgressBar Value="{Binding Progress}" Grid.Column="2" Grid.Row="2"/>
</Grid>
</Window>
The code-behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
namespace progressbar
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow() {
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e) {
var dc = DataContext as MainVM;
if (dc == null) return;
OpenFileDialog dialog = new OpenFileDialog();
var res = dialog.ShowDialog();
if (res == true) {
dc.Url = dialog.FileName;
dc.loadImage();
}
}
private void Button_Click_1(object sender, RoutedEventArgs e) {
var dc = DataContext as MainVM;
if (dc == null) return;
dc.loadImage();
}
}
}
And the ViewModel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Imaging;
using System.Windows.Input;
using System.ComponentModel;
namespace progressbar
{
public class MainVM : INotifyPropertyChanged
{
private BitmapImage bmi = null;
private Int32 _progress = 0;
private String _url = "";
public event PropertyChangedEventHandler PropertyChanged;
public Int32 Progress {
get { return _progress; }
set {
_progress = value;
NotifyPropertyChanged("Progress");
}
}
public String Url {
get { return _url; }
set {
_url = value;
NotifyPropertyChanged("Url");
}
}
public BitmapImage BitmapImg {
get { return bmi; }
set { bmi = value; }
}
public MainVM() { }
private void NotifyPropertyChanged(string propertyName = "") {
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public void loadImage() {
bmi = new BitmapImage();
bmi.BeginInit();
bmi.UriSource = new Uri(_url);
bmi.DownloadProgress += new EventHandler<DownloadProgressEventArgs>(bmi_DownloadProgress);
bmi.EndInit();
NotifyPropertyChanged("BitmapImg");
}
void bmi_DownloadProgress(object sender, DownloadProgressEventArgs e) {
Progress = e.Progress;
}
}
}
If you try to load an image from your hdd the progress will not be shown. Is there a way to do this?
Thanks in advance