【问题标题】:WPA XAML Datagrid Update requires a valid UpdateCommandWPA XAML 数据网格更新需要有效的 UpdateCommand
【发布时间】:2016-10-11 00:46:42
【问题描述】:

我正在尝试通过 DataSources 表适配器将 WPF 数据网格数据绑定的更改提交到 Microsoft SQL 服务器数据库,但我收到“更新需要有效的更新命令”错误。 我知道 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 事件似乎也没有更新的行数据,因为在我编辑第二行之前不会发生错误。

【问题讨论】:

  • 所以我的错误是我正在查看插入命令(我很累),而不是更新命令。事实上,向导并没有生成更新命令,即使它说它会生成。这可能是因为该表有两个主键。我写了一个 SQL 更新命令,错误就消失了。我仍然有数据保存之前必须输入数据两次的问题。因此,RowEditEnding 事件保存了“预先保存的数据”。如何强制本地提交,以便 SQL 更新使用新的用户编辑数据。

标签: c# wpf xaml datagrid sql-insert


【解决方案1】:

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

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

第二个问题,即 DataGridRowEditEndingEvent 触发时未更新的行已通过执行 commitedit 解决。 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 数据网格没有事件机制来指示已提交的行更新。所以很高兴知道是否有人知道。

我也想知道这是否是 MVVM 方式?您认为可以全部在 XAML 端处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-23
    • 2010-10-09
    • 1970-01-01
    • 2013-09-05
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    相关资源
    最近更新 更多