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.