Hi All
Just trying out the Rolodex sample for Silverlight and trying to edit an existing company (T-Mobile) that has some existing contacts.
When I choose to edit the company displays correctly except in the Contacts grid the Rank isn't shown. If I change the company and save then when it refreshes the rank is shown correctly.
I suspect the problem is that the company is being loaded before the Ranks combobox has populated and so it can't display the correct rank using the RankID. I have proved this by adding a Reload button to the control that runs the GetCompany code again. When the control refreshes this time the Rank is displayed.
So, what's the solution to this? I'm thinking in the system I'm building I'm going to have lots of comboboxes - these will all need to be populated before the main root object is displayed.
Craig
Well, I've figured out the reason for this, and it's as I suspected.
The problem is that the CslaDataProvider - RanksData - doesn't finish loading the combobox before the CompanyData loading fires. So the data arrives too late.
I can get this to work by rejigging the code to run the RanksData load and only when that is complete do I load the Company. Clearly there needs to be a simple implementation of a pattern here - all of the CslaDataLoader objects need to finish loading their data before the main edit object loads its data.
Comments?
Craig
You should not see a significant delay if any in loading ranks.
Once those are in, your UI should rebind. I am actually surprised that
this is not working for you. But yes, if you have a lot of combo boxes
with large lists, and you think your users will be confused by a possible
slight delay in binding, you would need to do something to postpone main data
load until all supported data has been loaded.
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: cds
[mailto:cslanet@lhotka.net]
Sent: Monday, February 09, 2009 5:19 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] Rolodex Comany Edit - Rank not showing
Well, I've figured out the reason for this, and it's as I suspected.
The problem is that the CslaDataProvider - RanksData - doesn't finish
loading the combobox before the CompanyData loading fires. So the data arrives
too late.
I can get this to work by rejigging the code to run the RanksData load and
only when that is complete do I load the Company. Clearly there needs to be a
simple implementation of a pattern here - all of the CslaDataLoader objects
need to finish loading their data before the main edit object loads its data.
Comments?
Craig
I agree James - I'm sure this is a timing issue.
Sergey - are you saying that I can essentially bind in any order? I don't think this is the case. There's a IValueConverter in the equation - the RanksConverter that looks at the Data property of the RankData CslaDataProvider - if that's empty then it won't be able to set the select item on the combobox.
Craig
i came across similar and have been doing this:
LoadData is called from outside of the UserControl
CslaDataProviderDataChanged is called by each provider and updates a module level bool and then call OnDataLoaded();
OnDataLoaded checks all providers have loaded and then fires an event to the "calling" page to allow it to be shown.
I'm not sure if this is absolutely required but it has gotten over the types of probelms you describe.
Good to hear Sergey's opinion?
public
void LoadData(object parameter){
CslaDataProvider expenseProvider = this.Resources["ExpenseData"] as CslaDataProvider; CslaDataProvider categorysProvider = this.Resources["CategorysData"] as CslaDataProvider; CslaDataProvider callReasonsProvider = this.Resources["CallReasonsData"] as CslaDataProvider; CslaDataProvider callOutcomesProvider = this.Resources["CallOutcomesData"] as CslaDataProvider; CslaDataProvider competitorsProvider = this.Resources["CompetitorsData"] as CslaDataProvider; CslaDataProvider mileageReasonProvider = this.Resources["MileageReasonsData"] as CslaDataProvider; if (categorysProvider != null) { categorysProvider.Refresh(); } if (callReasonsProvider != null) { callReasonsProvider.Refresh(); } if (callOutcomesProvider != null) { callOutcomesProvider.Refresh(); } if (competitorsProvider != null) { competitorsProvider.Refresh(); } if (mileageReasonProvider != null) { mileageReasonProvider.Refresh(); } if (parameter == null && expenseProvider != null){
expenseProvider.FactoryMethod =
"CreateExpense";expenseProvider.Refresh();
}
else{
int expenseId; if (int.TryParse(parameter.ToString(), out expenseId) == true){
expenseProvider.FactoryParameters.Add(expenseId);
expenseProvider.FactoryMethod =
"GetExpense";expenseProvider.Refresh();
}
}
}
private
void DataProvider_DataChanged(object sender, EventArgs e){
CslaDataProvider provider = sender as CslaDataProvider; //System.Diagnostics.Debug.WriteLine( // "Entering DataProvider_DataChanged: " + DateTime.Now.ToString() + " / " + provider.FactoryMethod); if (provider.Error != null){
Globals.DisplayErrorMessage(THIS_PAGE, "DataProvider_DataChanged", provider);}
else{
switch (provider.FactoryMethod){
case "CreateExpense":_isExpenseDataLoaded =
true; break; case "GetExpense":_isExpenseDataLoaded =
true; break; case "GetCategorys":_isCategorysDataLoaded =
true; break; case "GetCallReasons":_isCallReasonsDataLoaded =
true; break; case "GetCallOutcomes":_isCallOutcomesDataLoaded =
true; break; case "GetCompetitors":_isCompetitorsDataLoaded =
true; break; case "GetMileageReasons":_isMileageReasonsDataLoaded =
true; break; default: break;}
OnDataLoaded();
}
}
public
void OnDataLoaded(){
if (_isExpenseDataLoaded &&_isCategorysDataLoaded &&
_isCallReasonsDataLoaded &&
_isCallOutcomesDataLoaded &&
_isCompetitorsDataLoaded &&
_isMileageReasonsDataLoaded &&
DataLoaded !=
null){
DataLoaded.Invoke(
this, EventArgs.Empty);}
}
Yes, essentially you should bind in any order. Combobox is
an unfortunate example though. It is really underdeveloped because it is
missing binding to SelectedValue property which is what is used pretty much all
the time. My recommendation is not to use SL Combobox as it stands right
now because you will be forced to write converters for each combobox, which is
kind of ridiculous. My suggestion is to follow one of the two routes:
extend combobox to provide SelectedValue or some other way to be able to bind
to a selected value or buy a third party controls kit that includes real
combobox
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: cds
[mailto:cslanet@lhotka.net]
Sent: Monday, February 09, 2009 7:33 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] RE: Rolodex Company Edit - Rank not showing
I agree James - I'm sure this is a timing issue.
Sergey - are you saying that I can essentially bind in any order? I don't
think this is the case. There's a IValueConverter in the equation - the
RanksConverter that looks at the Data property of the RankData CslaDataProvider
- if that's empty then it won't be able to set the select item on the combobox.
Craig
The only way now is to use SynchonizedProxy and arrange your
providers in XAML in correct order.
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: James Thomas
[mailto:cslanet@lhotka.net]
Sent: Monday, February 09, 2009 6:19 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] RE: Rolodex Company Edit - Rank not showing
Hi Sergey,
I've run to exactly the same problem this evening - I hadn't seen it before.
What happens is that sometimes (when the data load is quick) the combo box is
set to the correct selected item, otherwise it isn't. When it hasn't loaded
quickly enough, the UI doesn't rebind - it just leaves the combo unselected.
When I click on it, the list is there, ready to go. It's bizarre - you can open
and close the form - and sometimes the combos will be set correctly, and
sometimes they will be blank. What's a good way to preload the necessary
CslaDataProviders?
Thanks, James.
Copyright (c) Marimer LLC