Telerik radgrid and object updating..

Posts   
 
    
Posts: 1263
Joined: 10-Mar-2006
# Posted on: 15-Mar-2006 05:36:31   

Where is that LLBlGenObjectDataSource? I need it....... frowning

For all you telerik users, if anyone is looking for a solution, the below works. If anyone has anything better, let me know.

Question/Problem: In the telerik grid, when a row is updated, an update event is called. I attached the code below and it actually all works (ugly though, huh?). Anyway, initially it did NOT work until I set the IsDirty flag to true. From what I can tell in the docs, I should not have had to do this?


protected void RadGrid1_NeedDataSource(object source, GridNeedDataSourceEventArgs e)
{
   RadGrid1.DataSource = this.SomeObjectCollection;
}

protected void RadGrid1_UpdateCommand(object source, GridCommandEventArgs e)
{
   GridEditableItem editedItem = e.Item as GridEditableItem;
   ObjectEntity nt = new ObjectEntity((int)editedItem.GetDataKeyValue("ObjectId"));

    if (nt.Fields.State != EntityState.Fetched)
    {
        e.Canceled = true;
        return;
    }

    //Update new values
    Hashtable newValues = new Hashtable();
    //The GridTableView will fill the values from all editable columns in the hash
    e.Item.OwnerTableView.ExtractValuesFromItem(newValues, editedItem);

    try
    {
        IEntityField entityField;
        foreach (DictionaryEntry entry in newValues)
        {
             entityField = nt.Fields[(string)entry.Key];
             entityField.CurrentValue = System.ComponentModel.TypeDescriptor.GetConverter(entityField.ActualDotNetType).ConvertFrom(entry.Value);
        }
        nt.IsDirty = true;
        nt.Save();
    }
    catch (Exception ex)
    {
        e.Canceled = true;
    }
}


Otis avatar
Otis
LLBLGen Pro Team
Posts: 39872
Joined: 17-Aug-2003
# Posted on: 15-Mar-2006 09:11:05   

Even in asp.net 2.0, normal databinding (one way) should work fine. 2-way databinding in asp.net isn't available for llblgen pro code at the moment, so you've to manually perform the event handling.

Frans Bouma | Lead developer LLBLGen Pro
Anonymous
User
Posts: 0
Joined: 11-Nov-2006
# Posted on: 15-Mar-2006 14:17:59   

Thnaks for the post wayne, I use Teleriks controls with LLBLGEN too and yup, you get can some real ugly code. I guess looks aren't everything wink

Pete

Posts: 1263
Joined: 10-Mar-2006
# Posted on: 15-Mar-2006 15:21:27   

Otis, In the above thread, I think you missed my real question/issue. That is why do I have to set isDirty=True, when I am using the Fields[x].CurrentValue to set the new values?

Is there a way to avoid this?

What is happening above is I get a hashtable of all the values that we edited, even if they were not changed. So, ideally, I would set Fields[x].CurrentValue and if the value was different from the old one, it would change it and mark that field as 'dirty', which would cause the proper SQL to be generated.

As it is now, it would update every field I guess?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39872
Joined: 17-Aug-2003
# Posted on: 15-Mar-2006 21:01:11   

entity.SetNewFieldValue(index, value); or entity.SetNewFieldValue(name, value);

should be used instead of CurrentValue writes with IsDirty=true.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1263
Joined: 10-Mar-2006
# Posted on: 18-Mar-2006 00:38:12   

There were a few problems with the code I posted, most around the type conversion. Anyway, here is the fixed code


    private void RadGridHandleChanges(EntityBase entity, GridCommandEventArgs e, bool isUpdate)
    {
        GridEditableItem editedItem = e.Item as GridEditableItem;
        if (!isUpdate && entity.Fields.State != EntityState.Fetched)
        {
            e.Canceled = true;
            return;
        }

        //Update new values
        Hashtable newValues = new Hashtable();
        //The GridTableView will fill the values from all editable columns in the hash
        e.Item.OwnerTableView.ExtractValuesFromItem(newValues, editedItem);

        try
        {
            IEntityField entityField;
            foreach (DictionaryEntry entry in newValues)
            {
                entityField = entity.Fields[(string)entry.Key];
                if (entityField != null)
                {
                    //for some reason, numbers come back as strings, but booleans are really boolean and type converter blows!
                    if (entry.Value != null && entry.Value.GetType() == entityField.ActualDotNetType)
                        entity.SetNewFieldValue((string)entry.Key, entry.Value);
                    else
                        entity.SetNewFieldValue((string)entry.Key, System.ComponentModel.TypeDescriptor.GetConverter(entityField.ActualDotNetType).ConvertFrom(entry.Value));
                }
            }
            entity.Save();
        }
        catch
        {
            e.Canceled = true;
        }
    }


Call the above code with:


//Inside InsertCommand event
//for insert (e is the parameter from RadGrid_InsertCommabd method)
MyEntity entity = new MyEntity();
RadGridHandleChanges(entity, e, false);

//Inside UpdateCommand event
//for insert (e is the parameter from RadGrid_Update method)
MyEntity entity = new MyEntity(pkey);
RadGridHandleChanges(entity, e, true);

Also, one other note. Make sure AllowAutomaticInsert, AllowAutomaticUpdate, AllowAutomaticDelete are false in your grid.