How to lazy load image byte[] into a WPF image control?
In order to teach myself some basics of OData and MVVM I wrote a little WPF application to query the Employee entity on the Northwind OData service at http://services.odata.org/Northwind/Northwind.svc/
The Model code I wrote to query the Employee entity is below:
public static ObservableCollection<Employee> GetEmployeesFromNW()
{
NorthwindEntities nwEntities = new NorthwindEntities(
new Uri("http://services.odata.org/Northwind/Northwind.svc/"));
var emp = from e in nwEntities.Employees
select new Employee
{
FirstName = e.FirstName,
LastName = e.LastName,
BirthDate = e.BirthDate,
Photo = e.Photo
};
// Cast the resuts to an observable collection.
return new ObservableCollection<Employee>(emp.AsEnumerable());
}
This returns the data to the ViewModel as an Employee object which is then bound to a WPF View that contains a ListBox with TextBlocks and an Image control.
Basically everything works as expected and I learned a bunch, However when I run the app it takes a little while to load because the size of the OData response when the Photo object (byte[] data) is included in the results is ~260KB where as without the byte[] data the response is 7KB
So my question i开发者_如何学JAVAs what would be the best method to lazy (asynchronously) load the images so that the data is returned first and then the images continue to load as they are downloaded.
One method I thought about was downloading the Photo using a separate thread and writing the byte[] data to image files in a temp location, then set the Image source with a path to the temp file location.
Anyone have any better ideas?
Start by changing the way you are populating your model properties to do the image separately from the other three properties. Move the loading of the data on to a separate thread from the UI such as a background thread.
Then change the binding on the Photo to a Priority Binding, this will allow the UI to display a message in place of the image while the image is loading.
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.Text>
<PriorityBinding>
<Binding ElementName="MainWindow" Path="Slow" IsAsync="True" />
<Binding ElementName="MainWindow" Path="Medium" IsAsync="True" />
<Binding ElementName="MainWindow" Path="Fast" />
</PriorityBinding>
</TextBlock.Text>
</TextBlock>
精彩评论