在WPF中对DataGrid进行TwoWay绑定

时间:2011-10-21 09:59:43

标签: c# wpf xaml wpfdatagrid

我有一个WPF DataGrid,我正在使用

填充
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;

我希望在更改任何值或添加新行时使用双向绑定来更新数据库。这可能吗?

我的xaml代码是

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

当我运行此代码时,除PerP列之外的所有代码都是空的。

我很失落如何做到最好的方式,所以任何帮助都会非常感激。

3 个答案:

答案 0 :(得分:3)

除了“PerP”列之外,Bindings的所有DataGridTextColumn都指定了两次路径。例如:

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

此处Binding首先指定路径为“ProductCode”,然后将其指定为“IsSelected”。由于集合中的对象没有“IsSelected”属性,因此绑定到网格时,如果在调试器下运行此属性,则应在“输出”窗口中看到绑定错误。如果删除这些绑定的Path=IsSelected,则应正确绑定列值。

您的数据源是匿名类型的集合,因此var是必需的,但正如其他人所说,对该集合的双向绑定不适用于更新回源。

答案 1 :(得分:2)

如果“allLines”变量是DataTable,您可以将DataGrid的AutoGenerateColumns设置为true。
您也不需要使用“DataContext”属性,而是使用“ItemsSource” 像这样:

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

要根据更改更新数据库,请调用数据表的Update()方法,例如单击“保存”按钮。

如果“allLines”不是DataTable,那么删除这个地狱般的“var”关键字并告诉我们变量的真实性质=)

答案 2 :(得分:2)

您的allLines变量是匿名类型的可枚举。在C#中,匿名类型是只读的 - 无法编辑属性,并且无法保存更改。

尝试进行查询:

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();