Kolumna combobox w DataGridView wypełniana poprzez zapytanie SQL

0

Hej,

Mam problem z dynamicznym wypełnianiem kolumny typu Combobox w DataGridView.
Moim celem jest żeby pole combobox w kolumnie datagridview było automatyczne wypełniane za pomocą zapytania SQL z klauzulą WHERE, po zatwierdzeniu danych zlecenia lub po kliknięciu danego wiersza w datagridview.

Problem w tym, że nawet jeśli uda mi się wypełnić dane tak jakbym chciał to komórka nie zapisuje danego wyboru.
Walczę z tym od długiego czasu i będę wdzięczny za każdą pomoc.

Kod:

private void dgv_production_CellClick(object sender, DataGridViewCellEventArgs e)
        {
           dgv_production.BeginEdit(true);
            {
                con.Open();
                SqlCommand cmd = new SqlCommand("SELECT * FROM tblRegisteredLOT WHERE ID_Component ='" + dgv_production.Rows[e.RowIndex].Cells["iDComponentDataGridViewTextBoxColumn1"].Value.ToString() + "'", con);
                cmd.ExecuteNonQuery();
                con.Close();
                DataTable dtbl = new DataTable();
                SqlDataAdapter sda = new SqlDataAdapter(cmd);
                sda.Fill(dtbl);
                Numer_LOT.DataSource = dtbl;
                Numer_LOT.DisplayMember = "LOT_Number";
                Numer_LOT.ValueMember = "ID_LOT";
            }
            dgv_production.EndEdit();  
        }
0

Przykład WPF:
MainWindowViewModel:

namespace WPFApp
{
    public class MainWindowViewModel
    {
        public IList<MyItem> MyItems { get; private set; } = new ObservableCollection<MyItem>();
        public Random r = new Random();
    }
    public class MyItem
    {
        public MyItem(int val)
        {
            this.val = val;
        }

        public int val { get; private set; }
        public override string ToString()
        {
            return val.ToString();
        }
    }
}

MainWindowModel:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
          
        }

        private void hCB_DropDownOpened(object sender, EventArgs e)
        {
            Dispatcher?.Invoke(() =>
            {
                ViewModel.MyItems.Clear();
                ViewModel.MyItems.Add(new MyItem(ViewModel.r.Next()));
                ViewModel.MyItems.Add(new MyItem(ViewModel.r.Next()));
                ViewModel.MyItems.Add(new MyItem(ViewModel.r.Next()));
                ViewModel.MyItems.Add(new MyItem(ViewModel.r.Next()));
                ViewModel.MyItems.Add(new MyItem(ViewModel.r.Next()));
                ViewModel.MyItems.Add(new MyItem(ViewModel.r.Next()));
                ViewModel.MyItems.Add(new MyItem(ViewModel.r.Next()));
                ViewModel.MyItems.Add(new MyItem(ViewModel.r.Next()));
                ViewModel.MyItems.Add(new MyItem(ViewModel.r.Next()));
                ViewModel.MyItems.Add(new MyItem(ViewModel.r.Next()));
            });
        }

    }

MainWindowView:

<Window x:Class="WPFApp.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:WPFApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.DataContext>
            <local:MainWindowViewModel x:Name="ViewModel"/>
        </Grid.DataContext>
        <StackPanel>
            <ComboBox x:Name="hCB" DropDownOpened="hCB_DropDownOpened" ItemsSource="{Binding Path=MyItems}">
                
            </ComboBox>
        </StackPanel>
    </Grid>
</Window>

Działanie. Po tym jak rozwiniesz combobox rozpocznie się procedura wypełniania danych ItemsSource, czyli zbindowanej listy w ViewModel. Jeżeli wykonujesz jakieś długotrwałe operacje możesz to zrobić w oddzielnym wątku po kolei w punktach:

  1. Wywołane zdarzenie DropDownOpened
  2. Czyścisz listę w ViewModel
  3. Twoja lista może pokazać niestandardową animację np. "kręcącego się kółka". Uzyskasz to edytując ComboBox.ItemsPanel w taki sposób, że TemplateSelector pokazuje domyślny ItemsPanel gdy lista nie jest pusta. Gdy jest pusta pokazuje Twoją animację.
  4. Gdy Twój wątek zwróci dane wypełniasz listę

Na podstawie powyższego przykłądu 2 kliknięcia w ComboBox generują mi różne dane:
a)
screenshot-20201021194111.png
b)
screenshot-20201021194132.png

0

Aplikacje robię w WinFormie.
Potrzebuję tej apki do ułatwienia sobie kontroli nad użytymi komponentami w danych wyrobach (praca).
W sumie wszystko inne ogarnąłem tylko tutaj nie mogę posklejać zależności pomiędzy eventami w DataGridView.

Dzięki Grzegorzu za pomoc.
W wolnej chwili na pewno przeanalizuje i dam znać czy coś udało mi się z tego ulepić.

0

@urke
Parametrów używam tylko wprowadzania danych do tabel, a nie do ich listowania. Może to i błąd ale mi tak jest wygodnie.

private void btn_add_lot1_Click(object sender, EventArgs e)
        {
            try
            {
                foreach (DataGridViewRow row in dgv_production.Rows)
                {
                    con.Open();
                    SqlCommand cmd = new SqlCommand("INSERT INTO tblProduction (ID_OrderNumber, ID_LOT, SerialNumber) values (@ID_OrderNumber, @ID_LOT, @SerialNumber)", con);
                    cmd.Parameters.AddWithValue("@ID_OrderNumber", Convert.ToInt32(cbx_mfr_order.SelectedValue));
                    cmd.Parameters.AddWithValue("@ID_LOT", Convert.ToInt32(row.Cells["Numer_LOT"].Value.ToString()));
                    cmd.Parameters.AddWithValue("@SerialNumber", txt_sn.Text);
                    cmd.ExecuteNonQuery();
                    con.Close();
                }
                MessageBox.Show("Dane zostały zapisane!");
                txt_sn.Text = "";
                refresh_production_data();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

Dane typu komponentu (typu int) wprowadzam do jednej z tabel, gdzie jedynym stringiem jest numer seryjny (załącznik).
Później prezentuje je za pomocą widoku.

0

Chcę uzyskać tylko taką kolekcje obiektów (numery_LOT) dla combobox w wierszu jakie są przypisane dla danego komponentu w tabeli tblComponent.
Samo datatable wypełnia mi się dobrze i tak samo przypisuje DisplayMember oraz ValueMember.
Problem jest w tym, że po opuszczeniu komórki nie zapisuje mi wyniku edycji, a nie za bardzo wiem jaki event tutaj rozwiąże problem i jak miałbym go obsłużyć.

0

Czyli rozumiem, że nie wiesz jaki event obsłużyć po zmianie wartości rekordu "Component" aby wypełnić NUMER_LOT?

1 użytkowników online, w tym zalogowanych: 0, gości: 1