I'm trying to load a image asynchronously.
MainWindow code
public partial class MainWindow : Window
{
private Data data = new Data();
public MainWindow()
{
InitializeComponent();
this.DataContext = data;
}
private async void button_Click(object sender, RoutedEventArgs e)
{
data.Image = await Data.GetNewImageAsync();
}
}
Data class
public class Data : INotifyPropertyChanged
{
private BitmapImage _Image = new BitmapImage();
public BitmapImage Image { get { return _Image; } set { _Image = value; OnPropertyChanged("Image"); } }
public static BitmapImage GetNewImage()
{
return new BitmapImage(new Uri("http://www.diseno-art.com/news_content/wp-content/uploads/2012/09/2013-Jaguar-F-Type-1.jpg"));
}
public async static Task<BitmapImage> GetNewImageAsync()
{
return await Task.Run(() => GetNewImage());
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
WPF code
<Button Name="button" Click="button_Click">Image</Button>
<Image Grid.Row="1" Source="{Binding Path=Image, UpdateSourceTrigger=PropertyChanged}"></Image>
Problem
I get the exception:
System.ArgumentException: "Must create DependencySource on same Thread as the DependencyObject."
... in this row:
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
But if i change BitmapImage to string this code works fine.
What am I doing wrong?
When a BitmapImage is created in a background thread, you have to make sure that it gets frozen before it is used in the UI thread.
You would have to load it yourself like this:
Or shorter with
BitmapFrame.Create
, which returns an already frozen BitmapSource:Note that the second method requires to change the type of your
Image
property to BitmapSource (or even better, ImageSource), which would provide greater flexibility anyway.An alternative method without any manual download might look like shown below. It also does not require to freeze the BitmatImage, because it is not created in a Task thread.