I have a WPF DataGrid that I am filling using
var allLines = from Lines in ctx.InvoiceLines join PerPs in ctx.ProductsViews on Lines.ProductCode equals PerPs.ProductCode
where (Lines.BranchNo == BrNo) && (Lines.Docket == Docket)
select new { Lines.ProductCode, Lines.Description, Lines.Inv_Quantity, Lines.Grn_Quantity,
Lines.Inv_Price,Lines.Grn_Price,Lines.Inv_Total, Lines.Grn_Total, Lines.AnalCode,
Lines.Vat_Rate, Lines.GrnNo,Lines.Comment , PerPs.OuterUnits};
dgGrid.ItemsSource = allLines;
I want to use two way binding to update the database when any of the values are changed or when a new row is added. Is that possible?
My xaml code is
<DataGrid Grid.Row="3" x:Name="dgGrid" DataContext="{Binding}" FontSize="16" HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible" SelectionUnit="FullRow" SelectionMode="Extended" AutoGenerateColumns="False"
SelectionChanged="dgGrid_SelectionChanged" >
<DataGrid.Columns>
<DataGridTextColumn Width="Auto" Header="ProductCode" Binding="{Binding ProductCode, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="250" Header="Description" Binding="{Binding Description, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}" FontSize="14"/>
<DataGridTextColumn Width="61" Header="Inv_Quantity" Binding="{Binding Inv_Quantity, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="63" Header="Grn_Quantity" Binding="{Binding Grn_Quantity, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="59" Header="Inv_Price" Binding="{Binding Inv_Price, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="61" Header="Ord_Price" Binding="{Binding Grn_Price, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="72" Header="Inv_Total" Binding="{Binding Inv_Total, Converter={StaticResource Currency}, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="74" Header="Grn_Total" Binding="{Binding Grn_Total, Converter={StaticResource Currency}, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="58" Header="AnalCode" Binding="{Binding AnalCode, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="40" Header="Vat_Rate" Binding="{Binding Vat_Rate, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="Auto" Header="GrnNo" Binding="{Binding GrnNo, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="Auto" Header="Comment" Binding="{Binding Comment, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="Auto" Header="PerP" Binding="{Binding OuterUnits}" IsReadOnly="True"/>
</DataGrid.Columns>
<DataGrid.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightSteelBlue"/>
</DataGrid.Resources>
</DataGrid>
When I run this code all but the PerP column is empty.
I'm quite lost as to how to do the best way so any help will be very much appreciated.
If the "allLines" variable is a
DataTable
, you could just set your DataGrid'sAutoGenerateColumns
to true.You also need not to use the "DataContext" property, but "ItemsSource" instead.
Something like this:
To update back the database on changes, call the
Update()
method of your datatable, on a "Save" button click for example.If "allLines" is not a DataTable, then remove this hellish "var" keyword and tell us the true nature of the variable =)
Your
allLines
variable is an enumerable of an anonymous type. In C# anonymous types are read-only - the properties cannot be edited, and the changes can't be saved.Try making your query:
All the
Bindings
for yourDataGridTextColumn
besides the "PerP" column are specifying the path twice. For example:Here your
Binding
is first specifying the path to be "ProductCode" and then also specifying it to be "IsSelected". Since there is no "IsSelected" property on the objects in the collection that you are binding to the grid, if you run this under the debugger you should see binding errors in the Output window. If you remove thePath=IsSelected
for those bindings then the column values should be bound correctly.Your datasource is a collection of an anonymous type so the
var
is necessary, but as others have said two-way binding to that collection isn't going to work for updates back to the source.