TwoWay binding on a DataGrid in WPF

23,088

Solution 1

All the Bindings for your DataGridTextColumn besides the "PerP" column are specifying the path twice. For example:

<DataGridTextColumn Width="Auto" Header="ProductCode"  Binding="{Binding ProductCode, Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>

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 the Path=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.

Solution 2

If the "allLines" variable is a DataTable, you could just set your DataGrid's AutoGenerateColumns to true.
You also need not to use the "DataContext" property, but "ItemsSource" instead.
Something like this:

<DataGrid ItemsSource="{Binding Path=allLines.DefaultView}" ... />

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 =)

Solution 3

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:

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 Lines;

dgGrid.ItemsSource = allLines.ToList();
Share:
23,088
Noelle
Author by

Noelle

using .net and sql server and not SharePoint, unless I really really really have to....it's impossible....completely impossible. Does anyone actually enjoy SharePoint development?

Updated on October 22, 2020

Comments

  • Noelle
    Noelle over 3 years

    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.