Использование события, добавленного в несколько программно созданных элементов управления - PullRequest
0 голосов
/ 07 января 2019

Я отображаю запас товаров, составляющих продукт, пользователь должен иметь возможность обновлять размеры и количество этих товаров в DataGridView для каждого товара после выбора товара.

Я создаю DataGridViews и событие, позволяющее программно обновлять базу данных, поскольку каждый продукт может состоять из 1-5 единиц.

SqlCommand stockCommand;
SqlDataAdapter stockAdapter;
SqlCommandBuilder stockBuilder;
DataSet stockDs;
DataTable stockTable;

private void DisplayItems()
{
    string queryItems = "SELECT id_item, id_PF, Name, Type FROM Items WHERE id_PF = "+ PF_id + " AND Type = 'BE'";
    using (SqlConnection con = new SqlConnection(conStringLocal))
    {
        using (SqlCommand cmdStock = new SqlCommand(queryItems, con))
        {
        int i = 0;
        con.Open();
        SqlDataReader readerStock = cmdStock.ExecuteReader();

        while (readerStock.Read())
        {
            string itemName = readerStock["Name"].ToString();
        DisplayItemsStock(i, itemName);
        i++;
        }
    }
    }
}


private void DisplayItemsStock(int i, string item)
{
    DataGridView stock = new DataGridView();
    stock.KeyDown += new KeyEventHandler(stock_KeyDown);

    string queryItemStock = "SELECT id_stock, item_name, size, quantity FROM Stock WHERE item_name = '" + item + "'";
    SqlConnection con = new SqlConnection(conStringLocal);
    stockCommand = new SqlCommand(queryItemStock con);
    stockAdapter = new SqlDataAdapter(stockCommand);
    stockBuilder = new SqlCommandBuilder(stockAdapter);
    stockDs = new DataSet();
    stockAdapter.Fill(stockDs, "stock");
    stockTable = stockDs.Tables["stock"];
    con.Close();
    stock.DataSource = stockTable;

    panelStock.Controls.Add(stock);
}

private void stock_KeyDown(object sender, KeyEventArgs e)
{
    DataGridView stock = (DataGridView)sender;

    if (e.Keycode == Keys.Enter)
    {
    // Check different conditions and update if everything is good

    using (SqlConnection con = new SqlConnection(conStringLocal))
        {
        con.Open();
        stockAdapter.Update(stockTable);
        MessageBox.Show("Saved changes");
    }       
    }
}

Команда обновления выполняется только в последнем созданном DataGridView, когда мне нужно, чтобы он работал на всех них.

1 Ответ

0 голосов
/ 08 января 2019

Я полагаю, что вы столкнулись с этой проблемой, потому что эти переменные являются общими для вашего DataGridViews.

SqlCommand stockCommand;
SqlDataAdapter stockAdapter;
SqlCommandBuilder stockBuilder;
DataSet stockDs;
DataTable stockTable;

Например, когда DataGridView создается для первого элемента, stockCommand устанавливается на новый SqlCommand с использованием запроса для этого элемента. И адаптер, компоновщик, набор данных и таблица также создаются из этого. Проблема возникает тогда, когда для следующего элемента создается DataGridView. Теперь создается новый объект stockCommand с запросом следующего элемента. Точно так же адаптер, компоновщик, набор данных и таблица настроены на новые объекты для следующего элемента. Они больше не используют запрос для первого элемента.

Теперь, когда происходит событие нажатия клавиши, используются stockTable и stockAdapter, которые теперь используют запрос для последнего элемента. Следовательно, последний элемент - единственный, который обновляется.

Вы можете избежать этой проблемы, создав и сохраняя отдельные переменные команды, адаптера, компоновщика, набора данных и данных для каждого DataGridView. Вы можете сделать это с Dictionary или я сделал это с новым классом.

public class StockItem
{
  private const string conStringLocal = "Data Source=TestDatabase.sqlite;Version=3;";

  private readonly SqlCommand stockCommand;
  private readonly SqlDataAdapter stockAdapter;
  private readonly SqlCommandBuilder stockBuilder;
  private readonly DataSet stockDs;
  private readonly DataTable stockTable;

  public DataGridView StockDataGridView { get; }

  public StockItem(string item)
  {
    StockDataGridView = new DataGridView();
    StockDataGridView.KeyDown += new KeyEventHandler(stock_KeyDown);

    string queryItemStock = "SELECT id_stock, item_name, size, quantity "
      + "FROM Stock WHERE item_name = '" + item + "'";
    SqlConnection con = new SqlConnection(conStringLocal);

    stockCommand = new SqlCommand(queryItemStock, con);
    stockAdapter = new SqlDataAdapter(stockCommand);
    stockBuilder = new SqlCommandBuilder(stockAdapter);
    stockDs = new DataSet();
    stockAdapter.Fill(stockDs, "Stock");
    stockTable = stockDs.Tables["Stock"];
    con.Close();
    StockDataGridView.DataSource = stockTable;
  }

  private void stock_KeyDown(object sender, KeyEventArgs e)
  {
    DataGridView stock = (DataGridView)sender;

    if (e.KeyCode == Keys.Enter)
    {
      // Check different conditions and update if everything is good
      using (SqlConnection con = new SqlConnection(conStringLocal))
      {
        con.Open();

        stockAdapter.Update(stockTable);
        MessageBox.Show("Saved changes");
      }
    }
  }
}

Функция DisplayItems остается прежней. И DisplayItemsStock становится:

private void DisplayItemsStock(int i, string item)
{
  StockItem stockItem = new StockItem(item);
  panelStock.Controls.Add(stockItem.StockDataGridView);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...