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>
<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
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
proxy.UpdateObject(prod)
End Sub
Here is the complete code
Imports System.Collections.ObjectModel
Imports System.Data.Services.Client
Imports System.Diagnostics
Imports System.Data.Services.Client
Imports System.Diagnostics
Partial Public Class Page
Inherits UserControl
Inherits UserControl
Public Sub New()
InitializeComponent()
End Sub
InitializeComponent()
End Sub
Dim q As DataServiceQuery(Of Northwind.Products)
Dim proxy As Northwind.NorthwindEntities
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")
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 = 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
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
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
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
proxy.UpdateObject(prod)
End Sub
Friend Sub SaveComplete(ByVal ar As System.IAsyncResult)
proxy.EndSaveChanges(ar)
End Sub
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
proxy.BeginSaveChanges(AddressOf SaveComplete, Nothing)
End Sub
End Class
No comments:
Post a Comment