Code used to bind a datagrid on a form was automatically generated when setting up the entity framework. The issue I'm having is that if the user edits a cell, then immediately closes the form, the edit is not made back to the database.
Using this as a guide, I implemented the INotifyPropertyChanged event to handle this issue. But it's not capturing the non-committed edit like I expect. In fact, I'm wondering why INPC is needed at all.
I changed the class generated by the code generator from this:
'------------------------------------------------------------------------------ ' <auto-generated> ' This code was generated from a template. ' ' Manual changes to this file may cause unexpected behavior in your application. ' Manual changes to this file will be overwritten if the code is regenerated. ' </auto-generated> '------------------------------------------------------------------------------ Imports System Imports System.Collections.ObjectModel Partial Public Class tlkpProcedures_PartB Public Property CPT As String Public Property ProcedureName As String Public Property BillingAmount As Nullable(Of Decimal) Public Overridable Property tblBilling_PartB As ObservableCollection(Of tblBilling_PartB) = New ObservableCollection(Of tblBilling_PartB) End Class
to this:
'------------------------------------------------------------------------------ ' <auto-generated> ' This code was generated from a template. ' ' Manual changes to this file may cause unexpected behavior in your application. ' Manual changes to this file will be overwritten if the code is regenerated. ' </auto-generated> '------------------------------------------------------------------------------ Imports System Imports System.Collections.ObjectModel Partial Public Class tlkpProcedures_PartB Inherits PropertyChangedBase Public Property CPT As String Get Return _CPT End Get Set(value As String) _CPT = value RaisePropertyChanged("CPT") End Set End Property Private _CPT As String Public Property ProcedureName As String Get Return _ProcedureName End Get Set(value As String) _ProcedureName = value RaisePropertyChanged("ProcedureName") End Set End Property Private _ProcedureName As String Public Property BillingAmount As Nullable(Of Decimal) Get Return _BillingAmount End Get Set(value As Nullable(Of Decimal)) _BillingAmount = value RaisePropertyChanged("BillingAmount") End Set End Property Private _BillingAmount As Nullable(Of Decimal) Public Property UniqueID As Integer Public Overridable Property tblBilling_PartB As ObservableCollection(Of tblBilling_PartB) = New ObservableCollection(Of tblBilling_PartB) End Class
Code to bind form:
Public Class PartBProcedures_Lookup Private _ProceduresContext As New DentistAppointmentsContext Private _bolSaved As Boolean = False Public Sub New() ' This call is required by the designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. End Sub Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles MyBase.Loaded Dim TlkpProcedures_PartBViewSource As System.Windows.Data.CollectionViewSource = CType(Me.FindResource("TlkpProcedures_PartBViewSource"), System.Windows.Data.CollectionViewSource) 'Load data by setting the CollectionViewSource.Source property: 'TlkpProcedures_PartBViewSource.Source = [generic data source] _ProceduresContext.tlkpProcedures_PartB.Load() TlkpProcedures_PartBViewSource.Source = _ProceduresContext.tlkpProcedures_PartB.Local End Sub Private Sub Button_Click(sender As Object, e As RoutedEventArgs) _ProceduresContext.SaveChanges() _bolSaved = True End Sub End Class
Xaml:
<DataGrid x:Name="TlkpProcedures_PartBDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Margin="11,10,10,49" ItemsSource="{Binding}" EnableRowVirtualization="True" AutoGenerateColumns="False"><DataGrid.Columns><DataGridTextColumn x:Name="CPTColumn" Width="100" Header="CPT" Binding="{Binding CPT, UpdateSourceTrigger=PropertyChanged}"/><DataGridTextColumn x:Name="ProcedureNameColumn" Width="200" Header="Procedure Name" Binding="{Binding ProcedureName, UpdateSourceTrigger=PropertyChanged}"/><DataGridTextColumn x:Name="BillingAmountColumn" Width="SizeToHeader" Header="Billing Amount" Binding="{Binding BillingAmount, StringFormat={}{0:n2}, UpdateSourceTrigger=PropertyChanged}" /></DataGrid.Columns></DataGrid>
If I strip out all the INPC coding, the datagrid binds and saves as expected, as long as the user clicks off the edited cell and into another, then clicks on Save. If I use INPC, the user still has to click off the edited cell onto another, then click on Save. So I'm not sure what I'm gaining by using INPC.
Ultimately, I'd like for the user to have to avoid the Save button all together. I tried stripping out the Save code thinking that INPC would automatically save edits back to the datasource, with no luck.
So, my problem is: I'm not sure if I'm doing the right thing by using INPC, and if it is the right thing, then what am I doing wrong that it doesn't function like I expect?
Thanks.