如何使用 GridData 更新 TextBoxes 数据?

How to update TextBoxes Data using GridData?

关于下面的 MainWindow 屏幕,我想用 DataGrid 插入、更新和删除数据。我已经为数据创建了插入和删除选项,但是当我 运行 出现错误时,update 选项出现问题。 以及 GridData 中的 SubID(主键),我希望它在我插入新值或删除值时自动计算行数(1,2,3,...),因为如下所示主窗口显示当我插入一个新值时,row=35 不按顺序排列。 注意:我已将组合框(分包商)与数据库链接在一起,每次选择时都会在文本框中显示数据。

The MainWindow Display

The MainWindow.cs.xaml

        using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.IO;
using Microsoft.Win32;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
using System.Data;
using System.Configuration;
using System.Collections;

namespace BV_Desktop
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        SqlConnection conn = new SqlConnection("Data Source=DESKTOP-7J69E9N;Initial Catalog=DatabaseInfor;Integrated Security=True");


        public MainWindow()
        {
            InitializeComponent();
            fillcombobox();
            DisplayData();

        }

        private void Window_Loaded(object sender, EventArgs e)
        {
           
        }
        public void fillcombobox()
        {
            SqlConnection conn = new SqlConnection("Data Source=DESKTOP-7J69E9N;Initial Catalog=DatabaseInfor;Integrated Security=True");
            string sql = "Select * from Tb_Sub";
            SqlCommand cmd = new SqlCommand(sql, conn);
            SqlDataReader myreader;

            try
            {
                conn.Open();
                myreader = cmd.ExecuteReader();
                while (myreader.Read())
                {
                    string sname = myreader.GetString(1);
                    comboBox1.Items.Add(sname);

                }
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(ex.Message);
            }

        }

        private void comboBox1_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
        {

            SqlConnection conn = new SqlConnection("Data Source=DESKTOP-7J69E9N;Initial Catalog=DatabaseInfor;Integrated Security=True");
            string sql = "Select * from Tb_Sub where (Subcontractor)='" + comboBox1.SelectedItem+ "';";
            SqlCommand cmd = new SqlCommand(sql, conn);
            SqlDataReader myreader;

            try
            {
                txtClients.Text = string.Empty;
                txtDetails.Text = string.Empty;
                txtPO.Text = string.Empty;
                txtScope.Text = string.Empty;
                txtProjectNo.Text = string.Empty;
                txtZIG.Text = string.Empty;
                txtAmount.Text = string.Empty;
                txtInvoiceDate.Text = string.Empty;
                txtStatus.Text = string.Empty;

                conn.Open();
                myreader = cmd.ExecuteReader();
                while (myreader.Read())
                {
                    string clients = myreader.IsDBNull(2) ? null : myreader.GetString(2);
                    string contactdetails = myreader.IsDBNull(3) ? null : myreader.GetString(3);
                    string ponum = myreader.IsDBNull(4) ? null : myreader.GetString(4);
                    string scope = myreader.IsDBNull(5) ? null : myreader.GetString(5);
                    string projectno = myreader.IsDBNull(6) ? null : myreader.GetString(6);
                    string zigno = myreader.IsDBNull(7) ? null : myreader.GetInt32(7).ToString();
                    string amount = myreader.IsDBNull(8) ? null : myreader.GetSqlMoney(8).ToString();
                    string invoicedate = myreader.IsDBNull(9) ? null : myreader.GetDateTime(9).ToShortDateString();
                    string status = myreader.IsDBNull(10) ? null : myreader.GetString(10).ToString();

                    txtClients.Text = clients;
                    txtDetails.Text = contactdetails;
                    txtPO.Text = ponum;
                    txtScope.Text = scope;
                    txtProjectNo.Text = projectno;
                    txtZIG.Text = zigno;
                    txtAmount.Text = amount;
                    txtInvoiceDate.Text = invoicedate;
                    txtStatus.Text = status;
                }
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(ex.Message);
            }

        }
        private void btnOpenFiles_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = true;
            openFileDialog.InitialDirectory = @"c:\";
            if (openFileDialog.ShowDialog() == DialogResult)
            {
                string filename = openFileDialog.FileName;
                //txtbox.Text = filename;
            }
        }

        private void btn_Insert_Click(object sender, RoutedEventArgs e)
        {
            SqlConnection conn = new SqlConnection("Data Source=DESKTOP-7J69E9N;Initial Catalog=DatabaseInfor;Integrated Security=True");
            conn.Open();
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "insert into [Tb_Sub] (Subcontractor,Clients,ContactDetails,[P.O.Num],Scope,[Project No.],[ZIG No.],[Amount(AED)],InvoiceDate,Status) values('"+comboBox1.Text+"','"+txtClients.Text+"','"+txtDetails.Text+ "','" + txtPO.Text + "'," +
                "'" + txtScope.Text + "','" + txtProjectNo.Text + "','" + txtZIG.Text + "','" + txtAmount.Text + "','" + txtInvoiceDate.Text + "','" + txtStatus.Text + "')";
            cmd.ExecuteNonQuery();
            conn.Close();

            comboBox1.Text = "";
            txtClients.Text = "";
            txtDetails.Text = "";
            txtPO.Text = "";
            txtScope.Text = "";
            txtProjectNo.Text = "";
            txtZIG.Text = "";
            txtAmount.Text = "";
            txtInvoiceDate.Text = "";
            txtStatus.Text = "";
            DisplayData();

            MessageBox.Show("Record is Inserted");

        }
        private void DisplayData()
        {
            string ConString = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;

            string CmdString = string.Empty;

            using (SqlConnection conn = new SqlConnection(ConString))

            {
                CmdString = "SELECT Subcontractor,Clients,ContactDetails,[P.O.Num],Scope,[Project No.],[ZIG No.],[Amount(AED)],InvoiceDate,Status FROM Tb_Sub";

                SqlCommand cmd = new SqlCommand(CmdString, conn);

                SqlDataAdapter sda = new SqlDataAdapter(cmd);

                DataTable dt = new DataTable("Tb_Sub");

                sda.Fill(dt);

                dataGridView1.ItemsSource = dt.DefaultView;

            }
        }
        /*private void btn_update_Click(object sender, RoutedEventArgs e)
        {
            conn.Open();

            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandType = CommandType.Text;
                cmd.CommandText = $"update [Tb_Sub]  set Clients = '{txtClients.Text}', ContactDetails = '{txtDetails.Text}', [P.O.Num] = '{txtPO.Text}', Scope = '{txtScope.Text}',[project No.] = '{txtProjectNo.Text}',[ZIG No.] = '{txtZIG.Text}',[Amount(AED)] = '{ txtAmount.Text}',InvoiceDate = '{ txtInvoiceDate.Text }',Status = '{txtStatus.Text}' where Subcontractor = ' {comboBox1.Text }'";

                cmd.ExecuteNonQuery();
                conn.Close();
           

                comboBox1.Text = "";
                txtClients.Text = "";
                txtDetails.Text = "";
                txtPO.Text = "";
                txtScope.Text = "";
                txtProjectNo.Text = "";
                txtZIG.Text = "";
                txtAmount.Text = "";
                txtInvoiceDate.Text = "";
                txtStatus.Text = "";
                DisplayData();

                MessageBox.Show("Record is Updated.");
            
        }*/
        private void btn_update_Click(object sender, RoutedEventArgs e)
    {
        if (comboBox1.Text != "" && txtClients.Text != "" && txtDetails.Text != "" && txtPO.Text != "" && txtScope.Text != "" && txtProjectNo.Text != ""
            && txtZIG.Text != "" && txtAmount.Text != "" && txtInvoiceDate.Text != "" && txtStatus.Text != "")
        {
            cmd = new SqlCommand("update Tb_Sub set Cliets=@clients,ContactDetails=@contactdetails,P.O.Num=@ponum,Scope=@scope," +
                "Project No.=@projectno,ZIG No.=@zigno,Amount(AED)=@amount,InvoiceDate=@invoicedate,Status=@status" +
                " where Subcontractor=@sub", con);
            con.Open();
            cmd.Parameters.AddWithValue("@sub", comboBox1.Text);
            cmd.Parameters.AddWithValue("@clients", txtClients.Text);
            cmd.Parameters.AddWithValue("@contactdetails", txtDetails.Text);
            cmd.Parameters.AddWithValue("@ponum", txtPO.Text);
            cmd.Parameters.AddWithValue("@scope", txtScope.Text);
            cmd.Parameters.AddWithValue("@projectno", txtProjectNo.Text);
            cmd.Parameters.AddWithValue("@zigno", txtZIG.Text);
            cmd.Parameters.AddWithValue("@amount", txtAmount.Text);
            cmd.Parameters.AddWithValue("@invoicedate", txtInvoiceDate.Text);
            cmd.Parameters.AddWithValue("@status", txtStatus.Text);
            MessageBox.Show("Record Updated Successfully");
            con.Close();

        }
        else
        {
            MessageBox.Show("Please Select Record to Update");
        }
    }



        private void btn_delete_Click(object sender, RoutedEventArgs e)
        {
            conn.Open();
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = $"delete from [Tb_Sub] where Subcontractor= '{comboBox1.Text}'";
            cmd.ExecuteNonQuery();
            conn.Close();

            comboBox1.Text = "";
            txtClients.Text = "";
            txtDetails.Text = "";
            txtPO.Text = "";
            txtScope.Text = "";
            txtProjectNo.Text = "";
            txtZIG.Text = "";
            txtAmount.Text = "";
            txtInvoiceDate.Text = "";
            txtStatus.Text = "";
            DisplayData();
            MessageBox.Show("Record is Deleted.");
        }

        private void dataGridView1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DataGrid gd = (DataGrid)sender;
            DataRowView row_selected = gd.SelectedItem as DataRowView;
            
            if(row_selected !=null)
            {
                comboBox1.Text = row_selected["Subcontractor"].ToString();
                txtClients.Text = row_selected["Clients"].ToString();
                txtDetails.Text = row_selected["ContactDetails"].ToString();
                txtPO.Text = row_selected["P.O.Num"].ToString();
                txtScope.Text = row_selected["Scope"].ToString();
                txtProjectNo.Text = row_selected["Project No."].ToString();
                txtZIG.Text = row_selected["ZIG No."].ToString();
                txtAmount.Text = row_selected["Amount(AED)"].ToString();
                txtInvoiceDate.Text = row_selected["InvoiceDate"].ToString();
                txtStatus.Text = row_selected["Status"].ToString();
            }
        }

        private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
        {

        }

        private void txtProjectCount_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }
    }
    } 

The mainwindow.xaml

<Window x:Class="BV_Desktop.MainWindow"
        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:BV_Desktop"
        mc:Ignorable="d" FontFamily="Times New Roman"
                Loaded="Window_Loaded"
        Title="BVSubcontractor" Height="740.392" Width="743.887" Icon="/images/bureauveritas_logo.png">
    <Border Padding="10">
        <StackPanel>
         
            <TextBlock Text="SubcontractorName:" FontWeight="Bold"/>
            <ComboBox  x:Name="comboBox1" Padding="2" Margin="0,0,269,0" SelectionChanged="comboBox1_SelectionChanged_1" IsEditable="True" BorderThickness="1" >
                <ComboBox.Effect>
                    <DropShadowEffect Color="Gray" BlurRadius="3" ShadowDepth="2"/>
                </ComboBox.Effect>
            </ComboBox>

            <TextBlock Text="ProjectNum:" FontWeight="Bold"/>
            <ComboBox  x:Name="txtProjectCount" Padding="2" Margin="0,0,269,0" IsEditable="True" BorderThickness="1" SelectionChanged="txtProjectCount_SelectionChanged" >
                <ComboBox.Effect>
                    <DropShadowEffect Color="Gray" BlurRadius="3" ShadowDepth="2"/>
                </ComboBox.Effect>
            </ComboBox>

            <TextBlock Text="Clients:" FontWeight="Bold" />
            <TextBox x:Name="txtClients" Padding="2" Margin="0,0,269,0" />

            <TextBlock Text="ContactDetails:" FontWeight="Bold" />
            <TextBox x:Name="txtDetails" Padding="2" Margin="0,0,269,0" />

            <TextBlock Text="P.O.No.:" FontWeight="Bold" />
            <TextBox x:Name="txtPO" Padding="2" Margin="0,0,269,0" />

            <TextBlock Text="Scope:" FontWeight="Bold" />
            <TextBox x:Name="txtScope" Padding="2" Margin="0,0,269,0" />

            <TextBlock FontWeight="Bold" Text="ProjectNo.:"/>
            <TextBox x:Name="txtProjectNo" Padding="2" Margin="0,0,269,0" />

            <TextBlock Text="ZIG No.:" FontWeight="Bold" />
            <TextBox x:Name="txtZIG" Padding="2" Margin="0,0,269,0" />

            <TextBlock Text="Amount (AED):" FontWeight="Bold" />
            <TextBox x:Name="txtAmount" Padding="2" Margin="0,0,269,0" />

            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="213*" />
                    <ColumnDefinition Width="5*" />
                    <ColumnDefinition Width="95*"/>
                </Grid.ColumnDefinitions>

                <!-- invoicedate -->
                <StackPanel Grid.Column="0" Margin="0 0 10 0">
                    <TextBlock Text="InvoiceDate:" FontWeight="Bold" />
                    <TextBox x:Name="txtInvoiceDate" Padding="2" Margin="0,0,36,0" Height="20" />
                </StackPanel>

                <!-- invoiceNo. -->
                <Button x:Name="btnOpenFile" Click="btnOpenFiles_Click" Content="Open file" Margin="429,14,178,0" RenderTransformOrigin="0.133,0.651" Height="20" VerticalAlignment="Top" Grid.ColumnSpan="3"/>
                <TextBlock Text="InvoiceNo:" FontWeight="Bold" Margin="430,0,162,25" Grid.ColumnSpan="3" />
                <Button x:Name="btnOpenFile_Copy" Click="btnOpenFiles_Click" Content="Save" Margin="60,14,48,0" RenderTransformOrigin="0.133,0.651" Height="20" VerticalAlignment="Top" Grid.Column="2"/>

            </Grid>

            <TextBlock Text="Status:" FontWeight="Bold" />
            <TextBox x:Name="txtStatus" Padding="2" Margin="0,0,269,0" />
            <Grid Height="58" RenderTransformOrigin="0.499,0.097">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="415*"/>
                    <ColumnDefinition Width="208*"/>
                    <ColumnDefinition Width="68*"/>
                </Grid.ColumnDefinitions>
                <!--Insert Button-->
                <Button x:Name="btn_Insert" Content="New" Height="25" Margin="10,15,284,18" RenderTransformOrigin="-1.385,1.406" Click="btn_Insert_Click" >
                    <Button.Resources>
                        <Style TargetType="{x:Type Border}">
                            <Setter Property="CornerRadius" Value="5"/>
                        </Style>
                    </Button.Resources>
                </Button>
                <!--Update Button-->
                <Button x:Name="btn_update" Content="Update" Height="25" Margin="155,13,139,20" RenderTransformOrigin="-1.385,1.406" Click="btn_update_Click">
                    <Button.Resources>
                        <Style TargetType="{x:Type Border}">
                            <Setter Property="CornerRadius" Value="5"/>
                        </Style>
                    </Button.Resources>
                </Button>
                <!--Reset Button-->
                <Button x:Name="btn_delete" Content="Delete" Height="25" Margin="300,12,210,21" RenderTransformOrigin="-1.385,1.406" Click="btn_delete_Click" Grid.ColumnSpan="2">
                    <Button.Resources>
                        <Style TargetType="{x:Type Border}">
                            <Setter Property="CornerRadius" Value="5"/>
                        </Style>
                    </Button.Resources>
                </Button>
            </Grid>
            <DataGrid x:Name="dataGridView1" Background="LightGray" HorizontalScrollBarVisibility="Visible"  
 RowBackground="LightYellow" AlternatingRowBackground="LightBlue"  
 xmlns:local="clr-namespace:BV_Desktop" Height="157" SelectionChanged="dataGridView1_SelectionChanged" RenderTransformOrigin="0.489,1.873"  >
 
                <DataGrid.Columns>

                </DataGrid.Columns>
            </DataGrid>
            <!--DataGrid-->
        </StackPanel>
    </Border>

The error i got when for example, edit the ContactDetails

以下示例以非常基本的方式展示了如何实现更新逻辑。您必须扩展数据模型以满足您的要求(添加缺失的列等)。

关键是将DataTable绑定到DataGrid。然后将 DataGrid.SelectedItem 属性 绑定到依赖项 属性,例如 SelectedRow,它用作编辑表单字段的绑定源。所选项目是DataRowView。您可以通过绑定到 SelectedRow[ColumnName] 将每个 TextBox 直接绑定到相应的列。这将自动更新 DataGrid 和基础 DataTable.

使用SqlDataAdapter.Update()使用修改后的DataTable更新数据库。

为简单起见,示例基于由两列组成的table:SubID(主键)和SubcontractorSubID 应该是 read-only 并且由 DBMS 自动生成。它不会显示在 DataGrid 中,仅用于标识目标行,例如UPDATEDELETE SQL 操作。

MainWindow.xaml

<Window>
  <StackPanel>
    
    <!-- 
      Edit the Subcontractor column of the selected row from the below DataGrid.
      Editing the TextBox will automatically update the DataGrid due to the SelectedItem binding. 
    -->
    <TextBox Text="{Binding SelectedSubcontractorTableRow[Subcontractor]}" />
    <Button Content="Update Database" 
            Click="UpdateDatabaseOnClicked" />

    <DataGrid ItemsSource="{Binding SubcontractorTable}"
              SelectedItem="{Binding SelectedSubcontractorTableRow}"  
              AutoGenerateColumns="False">
      <DataGrid.Columns>
        <DataGridTextColumn Header="Subcontractor" Binding="{Binding Subcontractor}" />
      </DataGrid.Columns>
    </DataGrid>
  </StackPanel>
</Window>

MainWindow.xaml.cs

partial class MainWindow : Window
{
  public static readonly DependencyProperty SubcontractorTableProperty = DependencyProperty.Register(
    "SubcontractorTable",
    typeof(DataTable),
    typeof(MainWindow),
    new PropertyMetadata(default(DataTable)));

  public DataTable SubcontractorTable
  {
    get => (DataTable) GetValue(MainWindow.SubcontractorTableProperty);
    set => SetValue(MainWindow.SubcontractorTableProperty, value);
  }

  public static readonly DependencyProperty SelectedSubcontractorTableRowProperty = DependencyProperty.Register(
    "SelectedSubcontractorTableRow",
    typeof(DataRowView),
    typeof(MainWindow),
    new PropertyMetadata(default(DataRowView)));

  public DataRowView SelectedSubcontractorTableRow
  {
    get => (DataRowView) GetValue(MainWindow.SelectedSubcontractorTableRowProperty);
    set => SetValue(MainWindow.SelectedSubcontractorTableRowProperty, value);
  }

  public MainWindow()
  {
    InitializeComponent();
    this.DataContext = this;

    DisplayData();
  }

  private void DisplayData()
  {
    string connectionString = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;

    using (SqlConnection sqlConnection = new SqlConnection(connectionString))
    {
      string cmdString = "SELECT * FROM Tb_Sub";

      using (var selectCommand = new SqlCommand(cmdString, sqlConnection))
      {
        using (var dataAdapter = new SqlDataAdapter(selectCommand))
        {
          this.SubcontractorTable = new DataTable("Tb_Sub");
          dataAdapter.Fill(this.SubcontractorTable);
        }
      }
    }
  }

  // Update database using a DataTable
  private async void UpdateDatabaseOnClicked(object sender, RoutedEventArgs e)
  {
    string connectionString = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;

    using (SqlConnection sqlConnection = new SqlConnection(connectionString))
    {
      using (SqlCommand updateCommand = sqlConnection.CreateCommand())
      {
        // The actual update query will be automatically generated 
        // by the SqlDataAdapter based on the SELECT command
        updateCommand.CommandText = "SELECT * FROM Tb_Sub";

        using (var dataAdapter = new SqlDataAdapter(updateCommand))
        {
          SqlCommandBuilder builder = new SqlCommandBuilder(dataAdapter);
     
          // Generate UPDATE query
          builder.GetUpdateCommand();

          int updatedRowCount = dataAdapter.Update(this.SubcontractorTable);
          if (updatedRowCount > 0)
          {
            MessageBox.Show("Record is Updated");
          }
        }
      }
    }
  }
}