PriorityBinding in WPF

PriorityBinding derives from Binding and is a variation of MultiBinding, a type of binding where you specify multiple sources in your XAML.

Keeping your application responsive while under load is important. Assigning the UI thread to do time intensive work is asking for trouble as it will prevent the UI from updating. This will cause the application to appear unresponsive. The solution, of course, is to assign the task to a worker thread instead of the UI thread. In WPF binding this can be easily accomplished by setting the IsAsync property to true in the XAML. When the...

binding engine encounters the IsAsync property it spawns a worker thread to get the data, then marshals the work back to the UI thread when it is ready to update the target property.

 <TextBlock Text='{Binding Path=Year, IsAsync=True}' />

This snippet shows how to create an asynchronous binding. It's simple and easy, just the way you want it to be. But what happens if you want to inform the user that the work is going to take awhile or you have a situation where you have multiple data sources, not all of which are freely avaliable? For these scenarios you should replace the Binding class with the PriorityBinding class.

PriorityBinding derives from Binding and is a variation of MultiBinding, a type of binding where you specify multiple sources in your XAML. While you can have multiple source, only one of the sources is active at any time. WPF queries all specified sources in the PriorityBinding and the first source to return data is designated the active binding. If more than one of the sources returns data then WPF changes the active binding to the one with the highest priority.

The following code shows an example of a data source that exposes two bindable properties. The preferred source is the ColorsFromSlowSource property but the class also exposes the LoadMessage property which will serve as the lower priority data source.

 class SimulatedSource : INotifyPropertyChanged { public ObservableCollection
 
   LoadMessage { get { // this call will return data immediately return new ObservableCollection
  
   () { "Loading Data..." }; } } public ObservableCollection
   
     ColorsFromSlowSource { get { // this call is delayed var temp = new ObservableCollection
    
     (); temp.Add("Blue"); temp.Add("Red"); temp.Add("Green"); temp.Add("Yellow"); temp.Add("Orange"); Thread.Sleep(4000); return temp; } }

    
   
  
 

Next, it's time to setup the binding as shown in the following XAML.

 <Page.Resources> <data:SimulatedSource x:Key='source1' /> </Page.Resources> <Grid> <ListBox DataContext='{StaticResource source1}' Margin='20'> <ListBox.ItemsSource> <PriorityBinding> <!--highest priority sources are first in the list--> <Binding Path="ColorsFromSlowSource" IsAsync="True" /> <Binding Path="LoadMessage" IsAsync="True" /> </PriorityBinding> </ListBox.ItemsSource> </ListBox>

Let's take a look at the results of this binding at runtime. The first screenshot shows the ListBox populated with the data returned from the LoadMessage property in the data source. The second screen shot shows the results a few seconds later. In the later screenshot you can see the PriorityBinding has repopulated the ListBox with the higher priority data.

Figure 1 - Lowest priority binding applied.

Figure 2 - Highest priority binding applied.

In this example all the datasources came from the same business class. PriorityBinding works with any valid datasources, however, so the bindings could just as easily came from differents sources in different locations.

This was first published in March 2010

Dig deeper on Windows Presentation Foundation

0 comments

Oldest 

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

-ADS BY GOOGLE

SearchCloudComputing

SearchSoftwareQuality

SearchSOA

TheServerSide

SearchCloudApplications

Close