CslaDataProvider broke when updated to 3.6.3

CslaDataProvider broke when updated to 3.6.3

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


Turntwo posted on Saturday, June 27, 2009

I have a bit of code where I create a CslaDataProvider in code behind.  In this case the _init flag is set to true as soon as I instantiate the object, and doesn't seem to change to false when I set the values for the CslaDataProvider, so when I try to Refresh to get the data, nothing happens.  This worked before the upgrade to 3.6.3 ( which makes sense since the _init flag was just introduced). 

Code:
CslaDataProvider comboListProvider = new CslaDataProvider();
comboListProvider.ObjectType = uiProperty.ComboBoxList; // This is a NameValueList type
comboListProvider.FactoryMethod = "GetValueList";
comboListProvider.DataChanged += new EventHandler(provider_DataChanged);
comboListProvider.Refresh();

The provider works fine where I have defined it in XAML. 

I've tried various things to get this to work, including calling InitialLoad(), using DeferRefresh, Refresh()ing and then changing Property values, etc.  Nothing affected the _init value. 
I've also tried setting the Properties when I instantiate the object using {} syntax.  It doesn't help. 

So far the only way I've gotten this to work is using reflection to call EndInit, which is an undesirable solution for obvious reasons. 

This appears to be an introduced bug, but please let me know if I'm just not doing something right.

RockfordLhotka replied on Sunday, June 28, 2009

I am open to suggestions.

When used through XAML, BeginInit() and EndInit() are called, and those appear to be the only reliable way to know that the control is being initialized. And during initialization the XAML processing would otherwise trigger data retrieval when we don't want it to occur - which was the reason for adding the _init flag (to stop double-retrieval of data).

If you manually create an instance of the control and don't do what the WPF runtime does (calling those two methods) I'm not sure how the control can know the difference?

I suppose I could add a constructor overload that accepts a dummy parameter so you could call that other constructor and the control would know to set _init to true right away. But that's a magic cookie solution that would be a real hack/mess.

var dp = new CslaDataProvider(true); // true indicates we're skipping the init process

That seem really bad to me - so I'm open to suggestions for a better answer.

Turntwo replied on Monday, June 29, 2009

If the methods were public, then I could just call them, and mimic the behavior of the XAML, but they are protected. 

_init is initialized to true, but then also set to true in BeginInit.  Could _init be initialized to false, and then when the CslaDataProvider is instantiated in code it will remain false, but when instantiated in the XAML it will run BeginInit to set it to true and EndInit to set it back to false? 

I tried this, and it works, but I'm not sure if it breaks the reason for the _init flag in the first place.  I wouldn't expect it to, since in the XAML case BeginInit and EndInit are called around the BeginQuery call, and so the data retrieval wouldn't be triggered.  I'm not sure though, because I only get a single call to BeginQuery even in the XAML case - the _init flag is false (so it works, but not sure if I'm breaking something else). 

RockfordLhotka replied on Monday, June 29, 2009

If I recall correctly, the double-call scenario occurs when there's an exception in the data access. Yes, I'm pretty sure that was the problem - an exception in data access would cause the data provider to be re-invoked, so the user would see two error dialogs as the form loaded.

Can you try your change with an exception generated in the DAL during create/fetch?

Turntwo replied on Monday, June 29, 2009

I tested the change with an exception generated in Fetch for a CslaDataProvider created in XAML and through code-behind, in both cases I only received a single error message.  I'm going to go ahead with the change in my environment.  Thanks for the help. 

RockfordLhotka replied on Monday, June 29, 2009

Thanks for helping work through this. I'll add this as a change request to the task list.

Copyright (c) Marimer LLC