Address Line Disappearing on Datagrid

Address Line Disappearing on Datagrid

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


DeHaynes posted on Monday, September 11, 2006

I created a contact object which has and Addressess Collection which contain a series of Address objects.  I wanted to bind my address collection to a datagrid, so I had to add the following code to the ContactAddresses collection so that when a person starts entering data in the new line in the data grid, this code will create a new object.

protected override object AddNewCore()

{

ContactAddress result;

result = ContactAddress.NewContactAddress();

OnAddingNew(new AddingNewEventArgs(result));

Add(result);

return result;

}

My problem is this.  When I type the new line into the datagrid everything is fine until I get to the last item.  If I just hit enter, the focus will move to ANOTHER new line and the previous line I just got done typing disappears.  If I tell it to save the Contact, it tries to save an address with all fields set to null.

However, if after I finishing typing in the last field for a new line, I then click on an already existing address record.  The new address line stays on the datagrid and when I go to save it, things work like normal. 

These are my objects

public class Contact : BusinessBase<Contact>

public class ContactAddress : BusinessBase<ContactAddress>

public class ContactAddresses : BusinessListBase<ContactAddresses, ContactAddress

I have not done any modifications to the basic CSLA code except to implement my classes.  Anyone have any ideas?

DeHaynes replied on Monday, September 11, 2006

Further specifications. 

Record A is an existing record.  Record B is going to be my new record, so I go down to the new record line and start typing it.  Everthing works fine as long as I don't type go to the new record line after entering Record B.  If for any reason I go to the new record line without typing in a new record, as soon as I leave that line, I loose data.  So here is what I have done so far.

1.  Type in a new record but don't go to the new record line after the last field.  Instead I click on the first record.  All is fine.

2.  Type in a new record and allow it to go to the next, blank new record line.  All is ok until focus leaves the blank new record line.  Then I loose the record I just typed in.  The object still exists but all the data fields are set to null.

3.  Typed in two new record in a row and let the focus move to the blank new record line.  All is ok until focus leaves the blank new record line, then the first new record I typed in disappears from the DataGrid.  The object is still there but it has null values.

 

The Id for my Address objects are an int which is an Identity from the SQL2005 server.  So when a new object is created, there is no object Id.  Do you think that may have something to do with it?

 

DeHaynes replied on Monday, September 11, 2006

I am thinking the issue is in this code.

void System.ComponentModel.IEditableObject.CancelEdit()
{
   
if (_bindingEdit)
   {
      CancelEdit();
      
if (IsNew && _neverCommitted && EditLevel <= EditLevelAdded)
      {
         
// we're new and no EndEdit or ApplyEdit has ever been
         
// called on us, and now we've been cancelled back to
         
// where we were added so we should have ourselves
         
// removed from the parent collection
         if (Parent != null)
            Parent.RemoveChild(
this);
      }
   }
}

This is in Core.BusinessBase in the System.ComponentModel.IEditable section.  I think that If I can find an event in the datagrid after entering a record and then make it do a snapshop, then I would resolve my problem.

P.S.  I notice nobody is responding to my post, but I figured I may as well go through the semantecs so the next person has some reference.

 

DeHaynes replied on Monday, September 11, 2006

   I found the problem.  Because my ID for my object is the Primary Key from a table in Ms SQL2005, I didn't put a value in for the Object Id.  So every new object had an Id of zero (0).  So when ever you were on a new line and you went into edit mode and cancelled it, the code would remove every object with an Id of zero because that Id matched the object that was created for the line that you started editing. 

   I corrected the problem by putting a private static int value in my Address Class. 

static int NewAddressUniqueValue = 0;

When anything calls the NewContactAddress method to get a Contact Address, it calls decrements the value in NewAddressUniqueValue and assigns it to the Id of the ContactAddress object.  Now the ContactAddress has a unique Id and won't disappear when deleting empty objects from the collection.  There is no possibility of mix up with the real object Ids because they are values greater than 0 and the temporary ones are values less than or equal to zero.  Also when the object is persisted to the database, it doesn't pass it's Object Id along and thus it gets a real one when that happens.

So I hope this helps anyone who comes accross it.

vitorsilva replied on Sunday, September 24, 2006

THANK YOU SO MUCH!
i spent nearly 3 hours trying to understand what was happening and looking for some help here in the foruns...

DeHaynes replied on Monday, September 25, 2006

Glad I could help.  :)

Sakelun replied on Friday, October 27, 2006

Thanks! I almost spent 3 hours trying to find this problem myself, but I'm a wimp - before I go delving too deep I always check the forums to see if anyone else has run into what I have.

All of that said, I have an alternative solution that may help some. Rather than allow the datagrid to compare objects based on key data fields, I override Equals to force it to do a reference comparison instead when I know the object to be new:

        public override bool Equals(object obj)
        {
            if (IsNew)
            {
                return this == obj;
            }
            else
            {
                return base.Equals(obj);
            }
        }

Since I'm using an auto-incrementing key, a default value that duplicates across new datagrid rows is perfectly acceptable as long as the proper key is reflected back upon successful insertion.

- Scott




ajj3085 replied on Friday, October 27, 2006

Probably a better solution is to assign the temporary id.  What happens if you want to override == for one of your objects?  You're back to square one then..

Its easy enough to subclass BusinessBase (which you should be doing anyway) tohandle this for you automatically.

Copyright (c) Marimer LLC