Rolodex Comany Edit - Rank not showing

Rolodex Comany Edit - Rank not showing

Old forum URL: forums.lhotka.net/forums/t/6381.aspx


cds posted on Monday, February 09, 2009

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

cds replied on Monday, February 09, 2009

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

sergeyb replied on Monday, February 09, 2009

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

cid:_2_0648EA840648E85C001BBCB886257279
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



James Thomas replied on Monday, February 09, 2009

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.

cds replied on Monday, February 09, 2009

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

davido replied on Tuesday, February 10, 2009

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);

}

}

sergeyb replied on Tuesday, February 10, 2009

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

cid:_2_0648EA840648E85C001BBCB886257279
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



James Thomas replied on Thursday, February 12, 2009

This has been a useful discussion - it's something that is going to crop up regularly on the forum I expect (as more people get to know CSLA silverlight through the rolodex example). The way I've got around it is similar to davido - I chain the loading of my dataproviders and only load the main provider once the others are loaded. Not ideal though.

sergeyb replied on Tuesday, February 10, 2009

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

cid:_2_0648EA840648E85C001BBCB886257279
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