Need suggestion on binding a Child Object directly as a Model to a ViewModel

Need suggestion on binding a Child Object directly as a Model to a ViewModel

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


tikluganguly posted on Tuesday, October 26, 2010

Hi All,

       I have a grid with data filled from csla businesslistbase now when the user selects a single row and clicks on the edit button a popup is suppose to be opened and the data of the row is suppose to be displayed in the popup window for editing. 

          Now here is the problem, to do so i need to set the csla bussinessbase object of the selected row as model to the viewmodel of the popup. But as the businesbase class is actually the child of a businesslistbase class it cannot be directly set if ManageObjectLifetime is set to true. Again if we set it to false then i cannot get the option of cancel edit which is required in case the user decides to cancel his edits. 

   Again just to mention I am using it in Silverlight 4 with CSLA 4.0.1. Awaiting your reply.

Regards,

Tiklu

RockfordLhotka replied on Tuesday, October 26, 2010

You can leave ManageObjectLifetime as true, as long as either CancelEdit or ApplyEdit have been called before the popup closes. Here's the high level sequence of events:

  1. User selects item on main form (child EL unchanged, let's call this value S)
  2. Popup viewmodel is created with child (child EL elevated to S+1)
  3. Popup is displayed and shows viewmodel/view, user does their thing
  4. User clicks Cancel (viewmodel calls CancelEdit/BeginEdit so EL goes to S, then S+1)
  5. User closes popup (you handle Closing event w/ TriggerAction so viewmodel calls ApplyEdit so EL goes to S)
  6. User continues interacting with main form

The important thing is step 5 - you must ensure that either ApplyEdit or CancelEdit is invoked when the popup is closed.

tikluganguly replied on Wednesday, October 27, 2010

Hi Rocky,

          Thanks for the quick reply, but in my case I am assigning the child object explicitly to the model property of viewmodel and I am getting the error. As the child object is marked as child and cannot directly go to beginedit. Can you please guide me what I am missing in here

 

Regards

Tiklu

RockfordLhotka replied on Wednesday, October 27, 2010

I am confused. Nothing stops calling BeginEdit on a child object. In fact it is entirely normal to call BeginEdit on a child object - most datagrid controls always do this.

Exactly what exception are you getting?

tikluganguly replied on Thursday, October 28, 2010

Hi Rocky,

    Sorry my bad the problem is actually happening with BusinessListBase and not with BusinessBase. it is saying "BeginEdit is not valid on a child object". Actually my problem is with the businesslistbase object and not with businessbase object. my businesslistbase object is a child to a businessbase object and this businesslistbase is getting added to a separate viewmodel. It is something like this...i have a form which holds the actual businessbase object and i have multiple links in the form that opens separate "views" now each of these views are having separate viewmodel which is being tied to separate children of the the actual model. Now when I am having a child of type BusinessListBase tied to the model of the form (the model is again tied to the viewmodel of the form), I am having trouble with this businesslistbase object. Also in future I have requirement to create one editable grid in the same way.

   Hope I was been able to be clear about my requirement here. Please do suggest 

Regards

Tiklu

tikluganguly replied on Thursday, October 28, 2010

Hi Rocky,

          I am also getting one very peculear problem. As I said that the Order object is part of OrderList which is again comes as a child object to Customer. Now As I told you in my form for the OrderList View I am having a separate viewmodel (which is attached to a view with a grid in it showing the data) and assigning the OrderList (derived from BussinessListBase and which is a child of Customer BusinessBase Object) to the model. Now as we cannot edit BusinessListBase directly if the object is set as child, I am setting ManageObjectLifetime to false.

    Now as the Grid is also having another child form when I am opening it and saving the data it is working correctly. And the applyEdit is working fine for the Order objects and the object is getting properly added/edited in the Grid.

   But now when I am saving the main form I am getting one peculear edit level mismatch  in the businesrules of the order object. Could this be because I am disabling ManageObjectLifetime  in the list?

Hope I was been clear with my explanation. Thanks in advance for your reply.

Regards

Tiklu



 

tikluganguly replied on Thursday, October 28, 2010

Just to give some hint When this method is getting called from the main object 

BusinessBase.cs Line No 3303

 

protected override void AcceptingChanges()

    {

      ((IUndoableObject)FieldManager).AcceptChanges(this.EditLevel - 1, false);

      ((IUndoableObject)BusinessRules).AcceptChanges(this.EditLevel - 1, false);

 

      base.AcceptingChanges();

    }

And inside the businessrules object the editlevel is coming as 0. 

 

RockfordLhotka replied on Thursday, October 28, 2010

It is true that you can't directly call BeginEdit on a child collection.

I don't honestly remember why, this behavior goes back a very long time - very possibly to version 1.x.

The answer has always been to take a snapshot of the parent containing the collection and manage undo at that level.

tikluganguly replied on Friday, October 29, 2010

Hi Rocky,

            Any suggestion on what could be the best process to take the snapshot?

 

Regards

Tiklu

Kevin Fairclough replied on Friday, October 29, 2010

Have you thought of changing the model type to the root object and only binding to the SelectedItem in the dialog?

Kevin

Correction: On second thoughts  this wont work.  I think you need to set the Model by passing the SelectedItem to it, maybe?

 

RockfordLhotka replied on Friday, October 29, 2010

The simplest thing is probably to pass the parent object to the new viewmodel, since that viewmodel will be the one exposing the Cancel method too.

In other words, the root viewmodel of your popup/dialog window has to work against the parent object, because that's the level where you can manage undo. You might then have a child viewmodel for the list - with ManageObjectLifetime set to false on that viewmodel.

tikluganguly replied on Saturday, October 30, 2010

I tried that...my form viewmodel is having the root businessbase class which contains the businesslistbase property. I tried assigning this businesslistbase property to the child viewmodel of the view containing the grid showing the businesslistbase objects with manageobjectlifetime as false. But I am getting editlevel missmatch...any idea why?

tikluganguly replied on Saturday, October 30, 2010

Hi Rocky,

            I found the problem is occuring for one of the code that I have written. This is what I have written

 

public void AddChild(IPhoenixModelBase child)

        {

            child.MarkAsChild(this);

            this.InsertItem(this.Count, (C)child);            

        }

 

Now this code is inside businesslistbase. and the child is a BusinessBase object. When I am createing a new record and saving the form the editlevel is working fine. But when I am doing some edits and adding a new record I am getting the edit level miss match error. Please suggest

Thanks once more for your support

Regards

Tiklu

 

tikluganguly replied on Saturday, October 30, 2010

Just On an added note please do remember that my requirement is to add a child object only after it is being created with the reference of parent object which i am sending through explicit DataPortal.BeginCreate() method and once the user clicks on save/done button this object (which is actually an independant object). must be set child and added to the list. 

tikluganguly replied on Saturday, October 30, 2010

Also on an added note some of the child popups do have a grid in it..in that case also I am getting an editlevelmissmatch..please suggest

tikluganguly replied on Monday, November 01, 2010

I just figured out when i was doing add child after that i need to called one applyedit followed by a beginedit to adjust the editlevel of the added entity and then it starts working. Like the code given below

 

list.AddChild(model);

model.ApplyEdit();

model.BeginEdit();

Copyright (c) Marimer LLC