更新 DATAGRID 行以保存到 SQL

Posted

技术标签:

【中文标题】更新 DATAGRID 行以保存到 SQL【英文标题】:Updating DATAGRID row to save to SQL 【发布时间】:2016-09-04 03:01:24 【问题描述】:

大家好,我正在尝试了解如何将行保存和编辑到数据库中

private void BudgetGrid_RowEditEnding(object sender,
    DataGridRowEditEndingEventArgs e)

    SqlCommand gridcmd = new SqlCommand();
    SqlConnection rwConn = null;
    rwConn = new SqlConnection("server=localhost;" +
    "Trusted_Connection=yes;" + "database=Production; " + "connection
    timeout=30");
    gridcmd.Connection = rwConn;
    rwConn.Open();
    //gridcmd.CommandText =
    //"SELECT Id, Name, Quantity, Rate, Time FROM Budget";
    gridcmd.CommandText =
    "UPDATE Budget SET Id = @id, Name = @Name, " +
    "Quantity = @Qty, Rate = @Rte WHERE Time = @Time";

    SqlDataAdapter gridda = new SqlDataAdapter(gridcmd);
    string strId = "@id".ToString();
    int intID;
    bool bintID = Int32.TryParse(strId, out intID);
    string strName = "@Name".ToString();
    string strQty = "@Qty".ToString();
    int intQty;
    bool bintQty = Int32.TryParse(strQty, out intQty);
    string strRte = "@Rte".ToString();
    int intRte;
    bool bintRte = Int32.TryParse(strRte, out intRte);
    string strTime = "@Time".ToString();
    gridda.SelectCommand.Parameters.Add(
        new SqlParameter("@id", SqlDbType.Int));
    gridda.SelectCommand.Parameters["@id"].SqlValue = intID;
    gridda.SelectCommand.Parameters.Add(
        new SqlParameter("@Name", SqlDbType.VarChar));
    gridda.SelectCommand.Parameters["@Name"].SqlValue = strName;
    gridda.SelectCommand.Parameters.Add(
        new SqlParameter("@Qty", SqlDbType.Int));
    gridda.SelectCommand.Parameters["@Qty"].SqlValue = strQty;
    gridda.SelectCommand.Parameters.Add(
        new SqlParameter("@Rte", SqlDbType.Int));
    gridda.SelectCommand.Parameters["@Rte"].SqlValue = strRte;
    gridda.SelectCommand.Parameters.Add(
        new SqlParameter("@Time", SqlDbType.VarChar));
    gridda.SelectCommand.Parameters["@Time"].SqlValue = strTime;
    DataTable griddt = new DataTable("Budget");
    gridda.Fill(griddt);
    gridda.UpdateCommand =
        new SqlCommandBuilder(gridda).GetUpdateCommand();
    BudgetGrid.ItemsSource = griddt.DefaultView;
    gridda.Update(griddt);
    rwConn.Close();

显示正常。我可以编辑它,但是当我点击另一个选项卡时它不会更新它会返回到原始数据。

我浏览过的大部分代码要么已经过时,要么不是我想要的。

所以这里是数据库

这是应用程序

所以基本上如果我点击标签到下一行。在BudgetGrid_RowEditEnding 事件下,它应该更新数据库.. 但现在不是。

【问题讨论】:

您能否提供更多详细信息?我看不到您的更新查询。 我看到每个人都在 SQL 中使用更新查询,但是当我使用 cmd = new SqlCommand("UPDATE Budget", uniConn); 时,它只会给出一个错误 【参考方案1】:
SqlConnection uniConn = null;
SqlCommand cmd = null;
SqlDataAdapter sda = null;
DataTable dt = new DataTable();
uniConn = new SqlConnection(
    "server=localhost;" + "Trusted_Connection=yes;" +
    "database=Production; " + "connection timeout=30");
cmd = new SqlCommand("UPDATE Budget(id, Name, Quantity, Rate, Time)",
    uniConn);
uniConn.Open();
sda = new SqlDataAdapter(cmd);
sda.Fill(dt);
BudgetGrid.ItemsSource = dt.DefaultView;
uniConn.Close();

你忘记关闭连接了吗?

【讨论】:

如果此代码示例对您有帮助,请将此标记为答案。 这不是我要找的……我会告诉你的。更新帖子。 你忘记关闭连接了吗? 不可以看到连接已关闭uniConn.Close(); 我在回答中添加了这一点。您的实际帖子中没有uniConn.Close();【参考方案2】:

只需复制以下代码。我已经创建了你的所有东西并成功测试。而不是第一种方式,我试图让你走更流行的方式。因此,我花了一些时间来采用..

希望对你有帮助!

SqlDataAdapter da;
DataTable dt;

    private void Window_Loaded(object sender, RoutedEventArgs e)
    
        SqlConnection Conn = new SqlConnection();
        Conn.ConnectionString = yourConnectionString;
        Conn.Open();

        SqlCommand gridcomm = new SqlCommand();
        gridcomm.Connection = Conn;

        gridcomm.CommandText = "SELECT Id, Name, Quantity, Rate, Time FROM Budget";

        da = new SqlDataAdapter(gridcomm);

        SqlDataReader gridreader = gridcomm.ExecuteReader();
        while (gridreader.Read())
        
        
        gridreader.Close();

        dt= new DataTable("Budget");
        da.Fill(dt);

        dataGrid_Budget.ItemsSource = dt.DefaultView;

        Conn.Close();

    

    private void dataGrid_Budget_RowEditEnding(object sender, System.Windows.Controls.DataGridRowEditEndingEventArgs e)
    
        DataGridRow editedrow = e.Row;

        int row_index = (DataGrid)sender).ItemContainerGenerator.IndexFromContainer(editedrow);

        for (int k=0;k< 5;k++)
        
            DataGridCell cell = GetCell(row_index, k);
            TextBlock tb = cell.Content as TextBlock;

            if (k==1)
            
                dt.Rows[row_index][k] = tb.Text;
            
            else if (k == 4)
            
                if (tb.Text != "")
                
                    dt.Rows[row_index][k] = Convert.ToDateTime(tb.Text);
                
            
            else
            
                dt.Rows[row_index][k] = Convert.ToInt32(tb.Text);
            
        

        da.UpdateCommand = new SqlCommandBuilder(da).GetUpdateCommand();

        da.Update(dt);
    




    public DataGridCell GetCell(int row, int column)
    
        DataGridRow rowContainer = GetRow(row);

        if (rowContainer != null)
        
            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);

            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            if (cell == null)
            
                dataGrid_Budget.ScrollIntoView(rowContainer, dataGrid_Budget.Columns[column]);
                cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            
            return cell;
        
        return null;
    

    public DataGridRow GetRow(int index)
    
        DataGridRow row = (DataGridRow)dataGrid_Budget.ItemContainerGenerator.ContainerFromIndex(index);
        if (row == null)
        
            dataGrid_Budget.UpdateLayout();
            dataGrid_Budget.ScrollIntoView(dataGrid_Budget.Items[index]);
            row = (DataGridRow)dataGrid_Budget.ItemContainerGenerator.ContainerFromIndex(index);
        
        return row;
    

    public static T GetVisualChild<T>(Visual parent) where T : Visual
    
        T child = default(T);
        int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < numVisuals; i++)
        
            Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
            child = v as T;
            if (child == null)
            
                child = GetVisualChild<T>(v);
            
            if (child != null)
            
                break;
            
        
        return child;
    

【讨论】:

请注意,如果您在完成编辑之前移动另一行,您会看到 FormatException,但如果您在完成编辑后单击另一行就可以了。您可以使用 try 包装代码,然后 catch(FormatException)MessageBox.Show("请先完成编辑!"); 或者您可以通过好的关键字在 Google 上进行研究。 哇兄弟没想到你写了整个代码>。 很少有红色的东西..它不起作用..但你给了...比我要求的要多得多:D谢谢芽。我可以看到如何以及在哪里进行。 我无法向上箭头,我只有 14 个代表 谢谢,标记就足够了。你能告诉我红色的名字吗?如果您将鼠标放在它上面,Visual Studio 会自动建议您更正这些问题。在另外 3 种方法中,只需按照 Visual Studio 的建议添加一些所需的程序集,然后使用它的命名空间来使用 3 种其他方法,红色的东西就可以消失。【参考方案3】:

您的 SQL 语法必须像这样更正,

SqlCommand update_comm = new SqlCommand();
update_comm.Connection = Conn;
update_comm.CommandText = "UPDATE Budget SET id= @u_id, Name= @u_name  WHERE person= @psn";

var update_da = new SqlDataAdapter(update_comm);
update_da.SelectCommand.Parameters.Add(new SqlParameter("@u_id", SqlDbType.Int));
update_da.SelectCommand.Parameters["@u_id"].Value = yourintvalue;

update_da.SelectCommand.Parameters.Add(new SqlParameter("@u_name", SqlDbType.NVarChar));
update_da.SelectCommand.Parameters["@u_name"].Value = yourstringvalue;

update_da.SelectCommand.Parameters.Add(new SqlParameter("@psn", SqlDbType.NVarChar));
update_da.SelectCommand.Parameters["@psn"].Value = yourstringvalue;

var update_ds = new DataSet();
update_da.Fill(update_ds);

'UPDATE' 应与'SET' 一起使用。

如果你想用 DataGrid 的编辑行的值更新实际的 SQL 数据库,请试试这个。

da.UpdateCommand = new SqlCommandBuilder(da).GetUpdateCommand();

da.Update(griddt); 

【讨论】:

我不明白 WHERE 部分.. 如果我希望它占据整行...并更新它以发布图片 第二部分是我想做的,但是 DA 在哪里声明?我会在哪里使用它? hmm..第二部分可能用于更新整个表。因为您正在尝试使用 RowEditEnding,所以 WHERE 应该是 id= @k_id 以指示已编辑的行。我的建议是将数据表声明为类(事件之外)的字段中的全局变量,以在事件或方法之间共享值。然后你编辑DataGrid(数据表在里面),并运行带有编辑值的UPDATE命令,比如dt.Rows[0][1],这意味着第一行和第二列的值(从零开始的索引)。手动更新并手动从 SQL 数据库加载数据。否则,您需要尝试第二部分。 我不熟悉 SqlCommandBuilder。对不起,但是 where 应该是你使用的本地变量或我评论的全局变量。我的应用程序代码的方向使我对此不熟悉。但是,如果您有兴趣,您需要进行研究,可以参考我的案例***.com/questions/35835567/… 我将 DataTable 加载到 DataGrid 并更改了值并运行了 SqlCommandBuilder 代码。实际的 SQL 数据库已根据我的问题的标题进行了更新。 我建议你获取 DataTable dt = new DataTable();在加载事件之外并在 Class 的字段中声明为全局变量,以便您可以使用 DataTable 的初始值或编辑值。如果您手动更新 SQL 数据库并将 SQL 数据库的数据手动加载到 DataGrid(DataTable) 中,这应该可以工作,因为它是基本和直接的方式。现在,我还测试了将 DataTable 外部事件声明为 DataTable dt_budget 类的字段;

以上是关于更新 DATAGRID 行以保存到 SQL的主要内容,如果未能解决你的问题,请参考以下文章

在 DataGrid 中编辑后直接保存实体

如何使用实体框架从 DataGrid 更新数据库

在 DataGrid 上编辑多个单元格,然后保存到数据库

直接在 DataGrid 中插入、更新和删除行并将更改保存在数据库中

WPF Datagrid闪烁问题

WPF DataGrid - 如何自动退出编辑模式?