WPA XAML Datagrid更新需要有效的UpdateCommand

时间:2016-06-10 06:47:31

标签: c# wpf xaml datagrid sql-insert

我试图通过DataSources表适配器将WPF数据网格数据绑定更改提交到Microsoft SQL Server数据库,但我得到的是“更新需要有效的UpdateCommand”错误。 我知道DataSources向导是相当受限制的,但它已正确创建了一个INSERT语句。

INSERT INTO PartRevisions
             (imrPartID, imrPartRevisionID, imrShortDescription, imrLastMaterialCost)
VALUES (@imrPartID,@imrPartRevisionID,@imrShortDescription,@imrLastMaterialCost)

这是我的测试代码。

namespace WPFtest2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private WPFtest2.M1DataSet m1DataSet = new M1DataSet();
        private WPFtest2.M1DataSetTableAdapters.PartRevisionsTableAdapter m1DataSetPartRevisionsTableAdapter = new WPFtest2.M1DataSetTableAdapters.PartRevisionsTableAdapter();
        private System.Windows.Data.CollectionViewSource partRevisionsViewSource = new CollectionViewSource();

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            m1DataSet = ((WPFtest2.M1DataSet)(this.FindResource("m1DataSet")));
            // Load data into the table PartRevisions. You can modify this code as needed.
            m1DataSetPartRevisionsTableAdapter.Fill(m1DataSet.PartRevisions);
            System.Windows.Data.CollectionViewSource partRevisionsViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("partRevisionsViewSource")));
        }

        private void partRevisionsDataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
        {
            if (e.EditAction == DataGridEditAction.Commit)
            {
                try
                {
                    int rc = 0;
                    rc = m1DataSetPartRevisionsTableAdapter.Update(m1DataSet.PartRevisions);
                    MessageBox.Show("Row updated");
                }
                catch (Exception Ex)
                {
                    MessageBox.Show(Ex.ToString());
                }
            }
        }
    }
}

和XAML代码

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFtest2"
        xmlns:M1DataSetTableAdapters="clr-namespace:WPFtest2.M1DataSetTableAdapters" x:Class="WPFtest2.MainWindow"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Window.Resources>

        <local:M1DataSet x:Key="m1DataSet"/>
        <CollectionViewSource x:Key="partRevisionsViewSource" Source="{Binding PartRevisions, Source={StaticResource m1DataSet}}"/>

    </Window.Resources>
    <Grid >
        <DataGrid 
            x:Name="partRevisionsDataGrid" 
            AutoGenerateColumns="False" 
            EnableRowVirtualization="True" 
            ItemsSource="{Binding}"  
            RowDetailsVisibilityMode="VisibleWhenSelected" 
            DataContext="{StaticResource partRevisionsViewSource}"
            RowEditEnding = "partRevisionsDataGrid_RowEditEnding">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="imrPartIDColumn" Binding="{Binding imrPartID}" Header="imr Part ID" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="imrPartRevisionIDColumn" Binding="{Binding imrPartRevisionID}" Header="imr Part Revision ID" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="imrLastMaterialCostColumn" Binding="{Binding imrLastMaterialCost, Mode=TwoWay}" Header="imr Last Material Cost" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="imrShortDescriptionColumn" Binding="{Binding imrShortDescription}" Header="imr Short Description" Width="SizeToHeader"/>
            </DataGrid.Columns>
        </DataGrid>

    </Grid>
</Window>

似乎RowEditEnding事件没有更新的行数据,因为在编辑第二行之前不会发生错误。

1 个答案:

答案 0 :(得分:0)

第一个问题是通过在TableAdapter的UpdateCommand属性中手动创建insert命令来解决的。

UPDATE PartRevisions
SET       imrLastMaterialCost = @imrLastMaterialCost, imrAverageMaterialCost = @imrAverageMaterialCost, imrStandardMaterialCost = @imrStandardMaterialCost
WHERE (imrPartID = @imrPartID) AND (imrPartRevisionID = @imrPartRevisionID)

通过执行commitedit解决了DataGridRowEditEndingEvent触发时未更新的行的第二个问题。 WPF Datagrid Row Editing "ENDED" event

提交编辑的问题是它重新触发RowGridEndEdit。 有两种方法可以解决这个问题。

1-暂时删除事件处理程序。

        (sender as DataGrid).RowEditEnding -= partRevisionsDataGrid_RowEditEnding;
        (sender as DataGrid).CommitEdit();
        (sender as DataGrid).Items.Refresh();
        (sender as DataGrid).RowEditEnding += partRevisionsDataGrid_RowEditEnding;

或者 2 - 在代码中放置一个标志以防止这样的递归。

bool prdg_already_updating = false;
private void partRevisionsDataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
    if (e.EditAction == DataGridEditAction.Commit && !prdg_already_updating)
    {
        prdg_already_updating = true;
        (sender as DataGrid).CommitEdit();
        (sender as DataGrid).Items.Refresh();
        prdg_already_updating = false;
        m1_02DataSetPartRevisionsTableAdapter.Update(m1_02DataSet.PartRevisions);
        MessageBox.Show("Row updated");
    }

这似乎破坏了行为,ms datagrid没有事件机制来指示提交的行更新。所以如果有人知道一个人就很高兴。

我也有兴趣知道这是否是MVVM方式?你认为可以在XAML方面全部处理。