Dave Burke : Freelance .NET Web Developer specializing in Online Communities

Silverlight 2.0 Immersivity: Datagrid Two-Way Data Binding

The Silverlight 2.0 period of Immersivity continues with today's keywords being Silverlight 2.0 Datagrid; Silverlight 2.0 Two-Way Data Binding; 2-Way Data Binding; No-Way Data Binding. (Just joking with the last one.  HA! HA!)

For good or bad, I stuck with my master plan of not spending resources on Silverlight until 2.0 went RTM, so I have no experience with anything that came before.  I've learned quickly however that Silverlight 2.0 DataGrid data binding was changed in RC0 from the betas, and since a lot of information out there pertains to the betas I was stumped for a while getting my head around how to capture updated data and send it back to the Web Service.  That was today's mission.

Prior to 2.0 RC0, the Silverlight DataGrid supported events like CommittingCellEdit and CommittingRowEdit. The demise of those events is noted here in Scott Morrison's "RC0 Breaking Changes" post and discussed on several Silverlight.net threads like this one.  The best workaround seems to be using the TextBox LostFocus event in a TemplateColumn CellEditingTemplate. That's a bit tricky because the LostFocus event fires when you are on a different row, requiring you to keep a copy of the edited item.  For instance, using ((MyDataObject)dataGrid.SelectedItem) in a LostFocus() event would retrieve the wrong row.

Silverlight 2.0 really has made Two-Way Data Binding ridiculously simple, that is, once you get the initial concepts down and know what to type, like anything else.

The ridiculously simple process starts when adding a Service Reference in a Silverlight 2.0 class project. Visual Studio 2008 (SP1) wires up all of the property settings in the data class object for NotifyPropertyChanged and configures the class as an ObservableCollection<T>, making two-way data binding a cinch.  This is performed for both ASMX Web and WCF Services.

Before I describe how I captured Silverlight 2.0 DataGrid data updates and passed that data back to an .ASMX Web Service I must tell you that NONE of this is necessary if you simply want to pass the entire collection back to the database.  That truly is ridiculously simple and I may end up going that route, but before doing so I had to know how to capture individual changes and pass only changed records to my Web Service.

Interjection: I know we'll need to add record insertion and deletion into the mix. I will address that on another day and another post.

We're going to need two Observable Collections, one for the working collection and the second for the changed items. We also need to remember the ID of the record updated to support our LostFocus event.


private ObservableCollection<LaborPostWS> laborPosts =
          new ObservableCollection<LaborPostWS>();
private ObservableCollection<LaborPostWS> changes =
          new ObservableCollection<LaborPostWS>();
public int LaborID { get; set; }

 

Capturing the LaborID is performed in a DataGrid BeginningEdit event.


private void dg_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
{
    LaborPostWS _laborPost = (LaborPostWS)dg.SelectedItem as LaborPostWS;
    LaborID = _laborPost.LaborID;
}


Then on LostFocus a bit of LINQ populates the "changes" collection. I don't like having two LINQ statements, but it's peripheral and works for now.

 

private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
    LaborPostWS _laborPost = (from c in laborPosts
                              where c.LaborID == LaborID
                              select c).Single();

    LaborPostWS existing = (from c in changes
                            where c.LaborID == LaborID
                            select c).Single();

    if (existing != null)
        changes.Remove(existing);
    changes.Add(_laborPost);
}


Finally, the changed records are sent to my .ASMX Web Service with a Button OnClick event. The OnClick and Web Method are shown below. 

 

private void Submit_Click(object sender, RoutedEventArgs e)
{
    service.UpdateLaborPostsCompleted += new
           EventHandler<System.ComponentModel.AsyncCompletedEventArgs>
           (service_UpdateLaborPostsCompleted);
    service.UpdateLaborPostsAsync(changes);
}

 

[WebMethod]
public void UpdateLaborPosts(List<Jobs.LaborPostWS> laborPosts)
{
    LaborPostDataContext db = new LaborPostDataContext();
    foreach (Jobs.LaborPostWS _post in laborPosts)
    {
        postID = _post.PostID;
        scheduleDate = _post.ScheduleDate;
        db.dbvt_UpdateLaborDetails(_post.LaborID,
            _post.PhaseID,
            _post.ShiftID,
            Convert.ToDouble(_post.Hours),
            _post.ForemanID,
            _post.ScheduleDate,
            _post.PostID);
    }
}


Yeap, the DataGrid is shaping up nicely.  I'm still struggling through the "most ignorant developer in the world" stage, but we're now editing data!


Tomorrow we move on to embedded listboxes, establishing data relationships and setting default properties!

Comments (8) | Post RSS RSS comment feed

Posted on 10/22/2008 8:41:12 PM by Dave Burke
Categories: .NET | Silverlight
Tags: No tags for this post

Related posts

Comments

10/23/2008 5:25:20 AM Permalink

Pingback from alvinashcraft.com

Dew Drop - October 23, 2008 | Alvin Ashcraft's Morning Dew

alvinashcraft.com |

10/23/2008 9:11:35 PM Permalink

Nice one!

Time to connect to a WCF service!

Joseph Ghassan Lebanon |

10/23/2008 10:20:51 PM Permalink

Joseph, You stung me hard, man, only because I know you're absolutely right!  ASMX is doing the job for now, but I plan to move to WCF as you advise. I know it's where I need to be, but I'm spending all of my mental CPU cycles on Silverlight end points for now.  

Over the last year or so I let too many things slip, you see. WCF is one of the basic food groups that I've been neglecting. I'll be rectifying that!  Thanks for the good advice.

Dave Burke United States |

10/24/2008 5:56:40 AM Permalink

Trackback from Dave Burke

Silverlight 2.0 Immersivity: Datagrid to ComboBox Data Binding

Dave Burke |

10/24/2008 6:39:12 AM Permalink

Trackback from Community Blogs

Silverlight Cream for October 24, 2008 -- #405

Community Blogs |

10/26/2008 11:49:31 PM Permalink

Pingback from mgalinks.wordpress.com

2008 October 24 - Links for today « My (almost) Daily Links

mgalinks.wordpress.com |

11/1/2008 1:12:13 PM Permalink

Wow i have been stuck on this for ages i can do asp.net datagrid easy but silverlight got me stuck but thank you just need to change it for WCF thanks

David United Kingdom |

11/1/2008 1:26:37 PM Permalink

David, Sorry you have to make the WCF changes. The next time I'll be using WCF as well.  It was too many new aspects for me to take on the first time around.  Thanks for the comment!

Dave Burke United States |

Comments are closed

This site was built with the Sueetie .NET Open Source Community Framework. Learn more about Sueetie at Sueetie.com.