Not so fast guys...
You should have a try...catch...finally block to reset Me.RaiseListChangedEvents = True and to call ApplicationContext.LocalContext.Remove("cn") in case an error gets thrown.
c#
try
{
this.RaiseListChangedEvents = fasle;
// Create you connection here
// Add your connection to LocalContext here
this.ApplicationContext.LocalContext("cn") = cn;
// Do some more stuff here
}
catch
{
// Handle errors here if applicable
}
finally
{
this.RaiseListChangedEvents = true;
this.ApplicationContext.LocalContext.Remove("cn");
}
This way your Me.RaiseListChangedEvents = True and to ApplicationContext.LocalContext.Remove("cn") will always get called.
I'm spinning my wheels here, running into all kinds of quirky behavior with the ERLB. Unfortunately, I can't debug CSLA either to walk through to see what's going on due to some strange VS10 WCF behavior that I've previously posted about, and am taking a break from for the time being.
So I have an ERLB. I have a SL ListBox bound to it. There is an "Add" button that pops up a popup form. What should the workflow look like? Let's exclude MVVM to avoid complication.
So for example: view (page, uc, etc.) instantiates a new editable root and invokes BeginEdit(). Pass it to the popup form (via constructor, etc.). If user clicks "OK" button on popup, the underlying view adds the new editable root to the ERLB via Add(). Then, what happens next? Does the view invoke ER.ApplyEdit()? Does the view invoke ERLB.Save()? This is where I'm getting lost and why I suspect I'm running into issues.
Also, in the case of an Edit scenario. The user selects a item in the ListBox, grabs the bound ER, the view invokes BeginEdit(). User clicks "OK" button on popup, then ER.ApplyEdit() is invoked. OR user clicks "Cancel" button and ER.CancelEdit() is invoked. Is that all that needs to happen? Do I need to inform the ERLB of any of this?
I've looked through the samples that came with the CSLA SL vids and have modeled my ERLB the same way, but I'm not consuming it in the same fashion as the demos are, so running into issues there. Also, the book is unclear on consumption patterns of the ERLB.
Thanks!
If it hasn't been said before in this thread, ERLB is designed for one thing and one thing only: to support in-place datagrid editing where you want changes to a row to be saved as the user leaves that row. Any other use of the ERLB requires that you emulate data binding as expected by the ERLB.
Typically though, emulating data binding isn't too hard, since the ERLB expects very little. In fact, it just requires this:
These are all things a datagrid control does automatically through data binding. If you aren't using a datagrid control, then you need to do these things.
You can do them in your code-behind or viewmodel, but you need to emulate the actions of a datagrid.
Great, the edit part works awesome! However, ERLB.AddNew() doesn't seem to return a type. I'm using a VB.NET SL client, and its return type is Sub. This is strange, because if I dig far enough down the hierarchy, I see that AddNew() is defined on BindingList<T> as a method that returns type T.
What gives? If you have any immediate thoughts, please let me know. I'll keep digging on my end. It's pretty strange though...
I just answered this, though maybe in a different thread.
AddNew() doesn't exist as a concept in ObservableCollection. It did and does exist in BindingList, and it is a useful concept. So we added it to our OC in CSLA - so all the CSLA collections have it.
But in SL server access is async. Often AddNewCore() needs to call DataPortal.Create() in .NET - but that's BeginCreate() in SL - so AddNewCore() must be async in SL.
(as an aside, this was how we spent much of 2007 - add one async feature for SL and find that you need to a others as a result - quite the cascade effect!!)
So AddNewCore() in SL is different from in .NET, because it must support async. It doesn't have to actually be async, but it needs to follow the async pattern in case you want to use the data portal.
This means AddNewCore() is half the equation, and OnAddedNew() is the other half - the part that is invoked when the add is done.
A typical SL add new looks like this:
protected override void AddNewCore()
{
var item = new Item();
Add(item);
OnAddedNew(item);
}
If that needs to be async, you just change it so the Add(item) and OnAddedNew(item) calls occur in the async callback - such as the CreateCompleted event handler from the data portal.
btw, this is covered in the CSLA .NET for Silverlight video series, along with code examples.
Honestly, the videos are a bit difficult to find specific information due to no indexing. It's hard to keep track where something was covered, and I just don't have the time to sit there and watch an entire video again to grab that one nugget of information unfortunately. Don't get me wrong, the videos are great, it's just difficult to remember where everything was covered (video number and exact minute)
In addition, the samples that come with the vids do not use the ERLBs like I'm trying to use them. It's not creating the ERLB that is causing me the grief, it's manually manipulating the collection itself and the items contained within that is (due to lack of understanding how it works underneath the sheets, admittedely).
I know you said in a previous post that the ERLB is meant to be used with a datagrid, however, I need to quote you from chapter 5 in your latest book:
At times, applications need to retrieve a collection of child objects directly. To do this, you
need to create a root collection object. For instance, the application may have a WPF UI
consisting of a ListBox control that displays a collection of Contact objects. If the root object
is a collection of child Contact objects, the UI developer can simply bind the collection to the
ListBox (with an appropriate data template), and the user can edit all the objects in the list.
This is exactly the approach that I have decided to take (only with an Accordian), so it is important that I invoke methods explicitly against the ERLB.
Anyhow, thanks for all of your help.
I was just saying that the AddNewCore/OnAddedNew code is in the samples with the videos.
Your use of ERLB outside a datagrid is fine, but is not a mainstream scenario, so I wouldn't cover it in a book or video - unless it was an advanced tips and tricks book/video.
voodoo45:I'm fairly new to CSLA in general and am helping to do some developement on a framework built off csla. My confussion lies with root objects vs. collections. In looking at the templates, it doesn't look like these two items will work together. The Editable root's GetEditableRoot factory method takes an id where as the collection wants to pass in a datareader object. Also, in the DataPortal_Update method of the collection object, it calls DeleteSelf, Insert, and Update all of which do not exist in the root object. The reason I ask is that this is the way things have been set for implementation and I'm having a bugger of a time figuring out how things will wire up. I noticed that the child collection is the same way. If the editable root object were changed to an editable child object everything would work fine from what i can tell. Is there no collection object that is meant to work directly with the EditableRoot object, or do I need to go through and make a bunch of changes to one of the collection objects to make this work? Thanks for the help.
V
FYI - the VB templates are not 100% complete (or correct).
I think the C# templates are maintained by Rick Supit and are in better shape.
You can also check out:
http://www.onelittlevictory.com for sample BOs and a basic discussion of each region.
Joe
Copyright (c) Marimer LLC