Ken Tucker Blog

Adventures in .net

Silverlight 2 RC0 DataGrid CommittingEdit work around

Sunday, October 5, 2008

In Silverlight 2 Beta 2 DataGrid had a CommittingEdit event which was a great event to update the data in an ado.net dataservice.   Unfortunately this event was removed in the RC0 of the datagrid.  As a work around Jonathan Shen suggested using a template column and using the LostFocus event to update your dataservice data.

 

 

                 <data:DataGridTemplateColumn Header="Command">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding FirstName}"></TextBlock>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                        <data:DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate>
                                <TextBox Text="{Binding FirstName}" LostFocus="TextBox_LostFocus"></TextBox>   //you can detect other events.
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellEditingTemplate>
                    </data:DataGridTemplateColumn>

 

Well this works fine but I don't want to have to define all my columns this way.  Sometimes it is nice to just let the datagrid autogenerate the columns. So I decided to use the DataGrid's PreparingCellForEdit to add the handler for the LostFocus event.  Couple of other things you need to do.  First Remove the old event handler so the event does not fire multiple times.  Second we need a variable to keep track of the item that was edited when the lost focus event is fired we will be on another record.

 

Dim prod As Northwind.Products

Private Sub dgProducts_PreparingCellForEdit(ByVal sender As Object, ByVal e As System.Windows.Controls.DataGridPreparingCellForEditEventArgs) Handles dgProducts.PreparingCellForEdit
    RemoveHandler e.EditingElement.LostFocus, AddressOf Textbox_LostFocus
    AddHandler e.EditingElement.LostFocus, AddressOf Textbox_LostFocus
    prod = DirectCast(dgProducts.SelectedItem, Northwind.Products)
End Sub

Friend Sub Textbox_LostFocus(ByVal sender As Object, ByVal e As EventArgs)
    proxy.UpdateObject(prod)
End Sub

 

Here is the complete code

 

Imports System.Collections.ObjectModel
Imports System.Data.Services.Client
Imports System.Diagnostics

Partial Public Class Page
    Inherits UserControl

    Public Sub New()
        InitializeComponent()
    End Sub

    Dim q As DataServiceQuery(Of Northwind.Products)
    Dim proxy As Northwind.NorthwindEntities

    Private Sub Page_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        Dim address = New Uri(Application.Current.Host.Source, "../WebDataService1.svc")

        proxy = New Northwind.NorthwindEntities(address)

        Dim qry = From p In proxy.Products Select p
        q = CType(qry, Global.System.Data.Services.Client.DataServiceQuery(Of Northwind.Products))

        q.BeginExecute(AddressOf ProductsLoaded, Nothing)

    End Sub

    Friend Sub ProductsLoaded(ByVal ar As System.IAsyncResult)
        Dim c = q.EndExecute(ar)
        Dim d As New ObservableCollection(Of Northwind.Products)
        For Each p In c
            d.Add(p)
        Next
        Dim GetOnRightThread As New SetTheDataSource(AddressOf SetDataSource)
        Dispatcher.BeginInvoke(GetOnRightThread, New Object() {d})
    End Sub

    Delegate Sub SetTheDataSource(ByVal d As ObservableCollection(Of Northwind.Products))

    Friend Sub SetDataSource(ByVal d As ObservableCollection(Of Northwind.Products))
        dgProducts.ItemsSource = d
    End Sub

    Dim prod As Northwind.Products

    Private Sub dgProducts_PreparingCellForEdit(ByVal sender As Object, ByVal e As System.Windows.Controls.DataGridPreparingCellForEditEventArgs) Handles dgProducts.PreparingCellForEdit
        RemoveHandler e.EditingElement.LostFocus, AddressOf Textbox_LostFocus
        AddHandler e.EditingElement.LostFocus, AddressOf Textbox_LostFocus
        prod = DirectCast(dgProducts.SelectedItem, Northwind.Products)
    End Sub

    Friend Sub Textbox_LostFocus(ByVal sender As Object, ByVal e As EventArgs)
        proxy.UpdateObject(prod)
    End Sub

    Friend Sub SaveComplete(ByVal ar As System.IAsyncResult)
        proxy.EndSaveChanges(ar)
    End Sub

    Private Sub btnSave_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnSave.Click
        proxy.BeginSaveChanges(AddressOf SaveComplete, Nothing)
    End Sub
End Class


kick it on DotNetKicks.com
Filed Under: Silverlight

Comments (4) -

BUsby Seo Test said:

nice post.,by the way i am newbie on silverlight.thx for share

ianimaru said:

nice explanation, thank's

Busby seo test said:

very nice, and thanks

Comments are closed