Hi
I have 2 Tables in a typical Master-Detail relationship :
1) AcctGrps is the Master table. It has 2 columns : AcctGrpCd and AcctGrpName, with AcctGrpCd being the PK.
2) Accts is the Detail table. It has 3 columns : AcctCd, AcctName and AcctGrpCd, with AcctCd being the PK. Thus, each Account has a single AcctGrpCd.
I have a WPF DataGrid in my Window, which displays the Accts data, in the following DataGridColumns :
1) AcctCd DataGridTextColumn
2) AcctName DataGridTextColumn
3) AcctGrpCd DataGridTextColumn
4) AcctGrpName DataGridComboBoxColumn : This column should be bound such that it displays the AcctGrpName from the AcctGrps table, corresponding to the AcctGrpCd in each Row.
I am retrieving both Tables from the DB, and returning them in DataTable.DefaultView objects, dynamically. (Since the tables are anyway created at runtime, I am not using an ObjectDataProvider.) The DataTable.DefaultView property is of type DataView, which implements the IbindingList interface and therefore provides Change Notifications.
Everything is working perfectly. The only problem is that when I change the selection in the AcctGrpName DataGridComboBoxColumn, the value displayed in the AcctGrpCd DataGridTextColumn changes only when I click on ANOTHER row. I would like the displayed AcctGrpCd to change IMMEDIATELY when the selection is changed in the AcctGrpName DataGridComboBoxColumn. How can I do this ?
The code is shown below :
<Window x:Class="WDataGridAcctsWGrpNames" ... ><DockPanel><StackPanel DockPanel.Dock="Top" Orientation="Horizontal"><Button Click="btLoad_Click" Content="Load" Height="23" Margin="5" Name="btLoad" Width="75" /></StackPanel><DataGrid AutoGenerateColumns="False" DataContext="{Binding}" Height="215" DockPanel.Dock="Top" ItemsSource="{Binding}" Margin="10" Name="dgAccts" Width="407"><DataGrid.Columns><DataGridTextColumn Header="Acct No" Binding="{Binding AcctNo}" /><DataGridTextColumn Header="Acct Name" Binding="{Binding AcctName}" /><DataGridTextColumn Header="Acct Grp Cd" Binding="{Binding AcctGrpCd}" /><DataGridComboBoxColumn DisplayMemberPath="AcctGrpName" Header="Acct Group" ItemsSource="{Binding}" SelectedValueBinding="{Binding AcctGrpCd}" SelectedValuePath="AcctGrpCd" x:Name="dgccAcctGrps" /></DataGrid.Columns></DataGrid></DockPanel></Window> Private Sub btLoad_Click( ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Try ' Disable the Load button. btLoad.IsEnabled = False ' Display a Wait cursor. Me.Cursor = Cursors.Wait ' Load Acct Groups data. Me.LoadAcctGrps() ' Load Accts data. Me.LoadAccts() Catch ex As Exception MessageBox.Show( ex.Message, ex.GetType.ToString) Finally ' Enable the Load button. btLoad.IsEnabled = True ' Display a Default cursor. Me.Cursor = Cursors.Arrow End Try End Sub ' Load Acct Groups data. Private Sub LoadAcctGrps()… ' Code to obtain the Acct Groups DataTable … ' Obtain a reference to the Acct Groups DataTable. m_dtAcctGrps = m_dsAcctGrps.Tables(0) ' List-Bind the Account Groups DataGridComboBoxColumn to the Account Groups DataTable. dgccAcctGrps.ItemsSource = m_dtAcctGrps.DefaultView End Sub ' Load Accts data. Private Sub LoadAccts() … ' Code to obtain the Accts DataTable … ' Obtain a reference to the Accts DataTable. m_dtAccts = m_dsAccts.Tables(0) ' List-bind the Accounts DataGrid to the Accounts DataTable. dgAccts.DataContext = m_dtAccts.DefaultView End Sub
Please note that DataViews serve as the Binding Source, and they implement the IBindingList interface and therefore already provide Change Notifications.
Perhaps, this problem is being caused because the DataRow’s EndEdit() method is called implicitly, when the user clicks on another Row. I would like to call the EndEdit() method explicitly, but in which event ? The DataGridComboBoxColumn doesn’t provide a SelectionChanged event ! So, in which event can it be called ?
Secondly, does this sort of problem occur if the DataGrid is bound to a List(Of Acct) object and the DataGridComboBoxColumn to a List(Of AcctGrp) object ? I haven’t yet tried this approach and am wondering if this is the standard approach in WPF, rather than binding to a DataView. If so, is it to avoid this kind of a problem ?
Thanks.
Steven