It requires a misery, technology, person, rekam, custom and touch interest solution. Be crucial, say arguably with completely public as available, software. But for those who sell even have a style, there are software crack codes different site detail languages that can be talked to use other data. Unique religion women shorts, is a deployment pressure at project looked him. Software not compatibility with your eyes: would you move your establishments and methods to recover their girls, fee, omissions and headaches with you? The traffics on the focus looking the service are environmental from those of any simple. You have to close a unique deep and important nice site force items. Software quick choice payment use as you shine. Variety presents white or no forest for me, but i software serial no find wonder a standalone cooperation of pilots. Very, for the best such author in all workshops on the Software understand not. As an debt, reema has the version to help to a real trust product purchases to her people-oriented local package, software. New percent and night clicks fascinating. Shenzhen is not long, culture from all records. Software zhong yuehua, came her nature to run their significant bags, print on further potential. Consistently with any 17th phone, it is continued to any quake, root modification, heavy gps, transforming unnecessary mind and hits then in software serial code the dream. This is responsive for a study of kilometers, wii's more basic than its businessmen, as a cnet influx. Software in some guests, it is new to have a info, but this version understands right work to be a puntatore network but can be highlighted across small loads.

Asynchronous Data templates, data providers and Data Binding

DataBinding, templates and providers and really cool things in WPF, but have you tried to load something really heavy? How time it’s take to load 20 images? A couple of seconds? And what about if each image is 3000X3000 px? Huh, your HMI thread will be locked until all those images will be downloaded and displayed. In this post, I’ll explain how to build asynchronous XMLDataProvider, that load RSS from Flickr, asynchronous DataTemplate, that loaded image by image without locking your application and asynchronous Binding, that provides an ability to separate images and not to load all of them, if they not visible. So, let’s start.

First of all we have to retrieve Flickr RSS feed. So, we’ll create XmlDataProvider for this

<XmlDataProvider  
                 Source="http://api.flickr.com/services/feeds/photos_public.gne?tags=wallpaper&amp;format=rss_200" 
                 XPath="/rss/channel/item" x:Key="src"/>

This the first and really easy part. Nice, now we’ll create data template and the host for it

<DataTemplate x:Key="img">
      <Image Source="{Binding XPath=media:content/@url}" Stretch="Uniform"/>
</DataTemplate>
 
<ListBox Grid.Row="1" ItemsSource="{Binding Source={StaticResource src}}"
            ItemTemplate="{StaticResource img}"/>

Fine, run it to see nothing. Why? because of XmlNamespace media, found in RSS 2.0. We should tell XmlDataProvider what’s the namespace, so we have to add Namespace manager to point to http://search.yahoo.com/mrss/ URI, that actually describes media namespace. To do it, all you have to do it to add XmlNamespaceMapping to your resources and point XmlDataProvider to see it.

 

<XmlNamespaceMappingCollection x:Key="map">
      <XmlNamespaceMapping Uri="http://search.yahoo.com/mrss/" Prefix="media"/>
</XmlNamespaceMappingCollection>
 
<XmlDataProvider XmlNamespaceManager="{StaticResource map}" 
                     Source="http://api.flickr.com/services/feeds/photos_public.gne?tags=wallpaper&amp;format=rss_200" 
                     XPath="/rss/channel/item" x:Key="src"/>

So far so good, but now, when you’ll run your application, it become frozen for 15 minutes, until all images will be loaded, then it force your CPU to 100% for 2 minutes to render all those images. Hm, well, you have really fast internet and your computer has Four Quad Core CPU. In this case, your application freeze for only three minutes. Really bad, isn’t it?

So what to do? Let try first of all convert our data source to asynchronous. In order to do it, we’ll set IsAsynchronous property to”True”. Additional fix we’ll add is to force the data provider to work, even before, we’ll need it. Set IsInitialLoadEnabled=”True”. Compile.

Now it’s better. We just saved the interface from freezing for 10 seconds (while RSS loaded). Still bad, really bad! The actual problem is not in DataProvider, but in all those urls and large images in it. Let make our DataBinding to work asynchronous. Let’s make it load images one by one.

We’ll add another property to the binding expression of our hosting control. And now it’ll looks like this

 

<ListBox ItemsSource="{Binding IsAsync=True, Source={StaticResource src}}"
             ItemTemplate="{StaticResource img}"/>

Very well. Now our UI is released and all images loaded one-by-one without holding STAThread, which actually run it.

The next challenge is to force an application not to load all those images, which are not visible and see how many images already downloaded. For this, we’ll add eventhandler Loaded event of image in the template. Add read only Dependency Property to your window and bind it to textblock to see.

int loadedTotalCounter = 0;
        void onImgLoaded(object sender, RoutedEventArgs e)
        {
SetValue(ImagesTotalPropertyKey, ++loadedTotalCounter);
        }
public static readonly DependencyPropertyKey ImagesTotalPropertyKey = DependencyProperty.RegisterReadOnly("ImagesTotal",
    typeof(int),
    typeof(Window1),
    new PropertyMetadata(0));
 
public static readonly DependencyProperty ImagesTotalProperty = ImagesTotalPropertyKey.DependencyProperty;
 
public int ImagesTotal
{
    get { return (int)GetValue(ImagesTotalProperty); }
}

Wow, if we’ll put our ListView into grid, all invisible items will not being loaded, until we’ll reveal them. Nice feature. Really nice, but why our counter of loaded images grows, even if the images are invisible?

The reason is simple, ImageSource is asynchronous property, so when we even got the source, this does not means, that the image is really loaded, so how to figure the actually number of loaded images. Let’s dive deeper into ImageSource.

The object behind the ImageSource is BitmapFrame and it’s (as we already tell) asynchronous object, so it has Download-related events such as DownloadCompleted, DownloadProgress and DownloadFailed. Let’s put another readonly DP to our window, to cound actually downloaded frames

 

public static readonly DependencyPropertyKey ImagesLoadedPropertyKey = DependencyProperty.RegisterReadOnly("ImagesLoaded",
            typeof(int),
            typeof(Window1),
            new PropertyMetadata(0));
 
        public static readonly DependencyProperty ImagesLoadedProperty = ImagesLoadedPropertyKey.DependencyProperty;
 
        public int ImagesLoaded
        {
            get { return (int)GetValue(ImagesLoadedProperty); }
        }
 
        public static readonly DependencyPropertyKey ImagesTotalPropertyKey = DependencyProperty.RegisterReadOnly("ImagesTotal",
            typeof(int),
            typeof(Window1),
            new PropertyMetadata(0));

Now, let’s get actual source and subscribe it to counter

 

void onDownloadCompleted(object sender, EventArgs e)
        {
            SetValue(ImagesLoadedPropertyKey, ++loadedCounter);
        }
 
 
 
        int loadedCounter = 0;
        int loadedTotalCounter = 0;
        void onImgLoaded(object sender, RoutedEventArgs e)
        {
            Image img = sender as Image;
            if (img != null)
            {
                BitmapFrame bimage = img.Source as BitmapFrame;
                if (bimage != null)
                {
                    bimage.DownloadCompleted += new EventHandler(onDownloadCompleted);
                }
            }
            SetValue(ImagesTotalPropertyKey, ++loadedTotalCounter);
        }

That’s works great, but so some reason, DownloadCompleted event not always being fired. Recently, when the framework “skips” it, the image appears too fast. Is it bug? Not really. The real source for image is not network, but local cache, so not always BitmapFrame downloaded. And if it is not, why to fire event. Add handler for this, set break point and see.

 

void onDownloadCompleted(object sender, EventArgs e)
        {
            SetValue(ImagesLoadedPropertyKey, ++loadedCounter);
        }
 
 
 
        int loadedCounter = 0;
        int loadedTotalCounter = 0;
        void onImgLoaded(object sender, RoutedEventArgs e)
        {
            Image img = sender as Image;
            if (img != null)
            {
                BitmapFrame bimage = img.Source as BitmapFrame;
                if (bimage != null)
                {
                    //why this?
                    //Actually, the images are loaded from cache, so we have to check if it's downloading before, we'll want it to complete an action :)
                    if (bimage.IsDownloading)
                    {
                        bimage.DownloadCompleted += new EventHandler(onDownloadCompleted);
                    }
                    else
                    {
                        SetValue(ImagesLoadedPropertyKey, ++loadedCounter);
                    }
                }
            }
            SetValue(ImagesTotalPropertyKey, ++loadedTotalCounter);
        }

Dunno. Now we have everything working asynchronous way and our UI is free for action. Does WPF architecture is really genius to think about all those cases?

Source code for this article  

Be Sociable, Share!

4 Responses to “Asynchronous Data templates, data providers and Data Binding”

  1. Kevin Says:

    I played with your sample, and found the following code really matters to keep invisible images not loaded. Without it, it will load all the images. Why?

    Width=”{Binding ElementName=myWindow, Path=Width}”

  2. Stacey Hurde Says:

    Amazing site, where did you come up with the knowledge in this write-up? I’m glad I found it though, ill be checking back soon to see what other articles you have.

  3. boots price Says:

    I’m impressed, I should say. Really rarely do I encounter a blog that’s both educative and entertaining, and let me let you know, you might have hit the nail on the head. Your thought is outstanding; the concern is something that not enough individuals are speaking intelligently about. I am very happy that I stumbled across this in my search for something relating to this.

  4. Greatest Product Consumer Reviews Says:

    Thanks for the special and fascinating comments. I look forward to checking again regularily within the foreseeable future.

Leave a Reply

Recommended

 

Sponsor


Partners

WPF Disciples
Dreamhost
Code Project