Двухстороннее связывание с DataGrid в WPF - PullRequest
3 голосов
/ 21 октября 2011

У меня есть таблица данных WPF, которую я заполняю, используя

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 ]

3 голосов
/ 21 октября 2011

Все Bindings для вашего DataGridTextColumn, кроме столбца "PerP", указывают путь дважды. Например:

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

Здесь ваш Binding сначала указывает путь к «ProductCode», а затем также указывает, что он «IsSelected». Поскольку у объектов в коллекции, которые вы связываете с сеткой, нет свойства IsSelected, если вы запустите это в отладчике, вы увидите ошибки связывания в окне вывода. Если вы удалите Path=IsSelected для этих привязок, тогда значения столбцов должны быть правильно связаны.

Ваш источник данных является коллекцией анонимного типа, поэтому var необходим, но, как другие говорили, двусторонняя привязка к этой коллекции не будет работать для обновлений обратно к источнику.

2 голосов
/ 21 октября 2011

Ваша переменная 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();
2 голосов
/ 21 октября 2011

Если переменная "allLines" имеет значение DataTable, вы можете просто установить для вашей DataGrid AutoGenerateColumns значение true.
Вам также не нужно использовать свойство «DataContext», а вместо этого «ItemsSource».
Как то так:

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

Чтобы обновить базу данных при изменениях, вызовите метод Update() вашего объекта данных, например, нажав кнопку «Сохранить».

Если «allLines» не является DataTable, удалите это адское ключевое слово «var» и сообщите нам истинную природу переменной =)

...