This is a migrated thread and some comments may be shown as answers.

Combo box and asynchronous queries

8 Answers 131 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
Morgan McCollough
Top achievements
Rank 1
Morgan McCollough asked on 30 Jul 2010, 04:38 PM
I have a page set up for editing a single entity that has about 10-12 combo boxes. Most of the ItemsSource properties of these combo boxes are bound to ObservableCollections that are filled based on asynchronous queries. The main entity itself is also pulled down using an asynchronous RIA services query. I had a lot of trouble getting this page to work correctly because it seems that when the main entity is returned first, the combo boxes often fail to pick the correct selected item when their lists populate. Depending on the timing different combo boxes will come up blank when everything is finally loaded. This results in the underlying model property being set to null, which is very bad.

I have seen a lot of people on the net complaining about this sort of problem with combo boxes in general in Silverlight. I was able to improve the behavior by changing the view model so that the main entity was not loaded until the queries for all the combo box lists had all completed. But, the problem still persisted on occasion. I think it has to do with the timing of the ObservableCollection objects filling and the combo boxes themselves responding to those collection changed events.

One additional thing I did was to handle the final entity loaded event in the code behind and call cancel changes on the domain context at that point. That seemed to correct most of the issues, as the combo boxes would rebind to the correct selected values at that point. My worry is that this just seems a very ugly / brittle way of doing things. I wondered if anyone had any suggestions of a better way to handle this or whether there is something major I am missing.

By the way, I am using Silverlight 4 and Telerik build 2010.1.702.1040.

8 Answers, 1 is accepted

Sort by
0
Valeri Hristov
Telerik team
answered on 02 Aug 2010, 10:56 AM
Hello Morgan,

We fixed a few similar problems in RadComboBox, that were related to the delayed population of the Items collection. I believe all scenarios were covered, but we might missed something. I admit that your solution is a little bit ugly and I would not expect it to work like that. I would appreciate if you open a new support ticket and send me a simple project that could be used to observe and debug the problem. We will do our best to provide suggestions or fix the problems in RadComboBox if we find any.

Regards,
Valeri Hristov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Morgan McCollough
Top achievements
Rank 1
answered on 02 Aug 2010, 07:31 PM
So, there should have been fixes for that in the build I listed? I'll do some more experimentation and see if I can put together an example project.
0
Valeri Hristov
Telerik team
answered on 03 Aug 2010, 10:34 AM
Yes, but you are using the latest version of Q1 2010, that is supposed to contain the fix, so I suppose that we might missed something.

Greetings,
Valeri Hristov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Brian Sayatovic
Top achievements
Rank 1
answered on 20 Dec 2011, 04:31 PM
Can you elaborate on those fixes?  I'm plagued by similar problems (asynchronously loading both the values in the ItemsSource and the property holding the SelectedItem) using controls version 2011.2.0920.1040.
0
Valeri Hristov
Telerik team
answered on 21 Dec 2011, 05:14 PM
This thread is about a very old version of RadControls, most probably your problem is different. Could describe it in more detail?

Generally RadComboBox will keep the value of its SelectedValue property if its ItemsSource is empty. When you add an item in the ItemsSource the combobox will try to select it if it matches the SelectedValue, if the first item does not match, the control will not try to select items anymore. That's why we recommend setting the whole ItemsSource at once. Consider the following:
comboBox1.SelectedValue="one";

"result" is the collection that was returned by the async call and it contains strings, including the string "one" that will be selected:

// This will not work
var items = new ObservableCollection<string>();
comboBox1.ItemsSource = items;
foreach (var item in result)
{
    items.Add(item);
}

// This will work
var items = new ObservableCollection<string>();
foreach (var item in result)
{
     items.Add(item);
}
comboBox1.ItemsSource = items;

Regards,
Valeri Hristov
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Brian Sayatovic
Top achievements
Rank 1
answered on 21 Dec 2011, 08:19 PM
Bear in mind that we've built a complex application, so it's hard for me to pare it down it a simple scenario to be sure what is going on.  That said, let me try and explain what's going on.

We have a RadComboBox whose ItemsSource is bound to a view model property named Products that is an ObersavleCollection<Product>.  Its SelectedValue is bound to a view model property named SelectedProductId and a SelectedValuePath if "Id".

<telerik:RadComboBox ItemsSource="{Binding Products}" SelectedValue="{Binding SelectedProductId, Mode=TwoWay}" SelectedValuePath="Id" />

However, due to a variety of things, our system may choose to "reload" the collection of products at any time (e.g. someone else has added a new product, so our Silverlight code detects such an event and reacts by reloading the product list).  We accomplish this in the ObservableCollection<Product> by *clearing* the collection, firing off the async WCF call, and when it completes, adding the items back into the ObservableCollection.

It is my belief that when I clear the ObservableCollection<Product> that the SelectedValue is no longer present in the ObservableCollection<Product> so the RadComboBox believes "nothing is selected" and binds null into my SelectedProductId.  When the collection finally does load, still nothing is selected because the SelectedProductId has already been set to null.
0
Morgan McCollough
Top achievements
Rank 1
answered on 21 Dec 2011, 09:55 PM
This is still an issue for us, but I have not looked at the workaround in a while. Basically, we have a product edit page where a number of the individual properties are tied to combo boxes. We don't set the public product property in the view model until all other dependent collections have been loaded.

The one other thing we changed was to use a custom subclass of ObservableCollection that adds bulk upate methods like 'Reset' and 'AddRange' to the collection. These methods turn off the CollectionChanged event firing and just fire a single event when all items have been dealt with. This prevents the collection from firing an event for every added or removed item.

The other strategy we have tried is to have the default value of the collection be the entire entity list from the database, which is cached on the client side on app startup. We then perform dependent queries when the product page loads to pare down the lists, and call 'Reset' on each of the collections when the queries complete. That way the collections always contain either all the possible values from the DB, or the appropriate filtered list (they are never empty). Unfortunately, this approach is not always feasible.

Version: 2011.1.405.1040
0
Valeri Hristov
Telerik team
answered on 23 Dec 2011, 12:26 PM
Brian, you are correct - when the ItemsSource of RadComboBox is cleared the SelectedItem/Value properties are reset to null. However, if the ItemsSource is replaced, the property values are kept, but only if the new collection contains items that match them. To workaround this limitation you could try a variation of my previous suggestion (MVVM this time):
<telerik:RadComboBox SelectedValue="{Binding SelectedProductID, Mode=TwoWay}" ItemsSource="{Binding Products}" SelectedValuePath="ID" />

// in the view model, in the async callback method that retreives the new products list:
var products = new ObservableCollection<Product>();
foreach (var product in result)
{
     products.Add(product);
}
this.Products = products;
this.OnPropertyChanged("Products"); // in case the Products property does not raise changed event

This way the items source update will be made in one transaction and RadComboBox will automatically keep its SelectedItem/Value properties.

Regards,
Valeri Hristov
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Tags
ComboBox
Asked by
Morgan McCollough
Top achievements
Rank 1
Answers by
Valeri Hristov
Telerik team
Morgan McCollough
Top achievements
Rank 1
Brian Sayatovic
Top achievements
Rank 1
Share this question
or