DGV wiązanie dwukierunkowe

0

Potrzebuje podpowiedzi jak odzworować zmiany użytkownika na danych wyswietlanych w DataGridView na kolekcje ze zrodla danych tego DGV.

  • nie wiem jak zrobić wiązanie dwukierunkowe.
  • ewntualne mam jeszcze opcje wylapywania zdarzenia dgv_CellValueChanged i na podstawie DataGridViewCellEventArgs odszukiwać konkretne wlasciwosci i aktualizowac obiekty w kolekcji

DGV korzysta z BindingSource, a jako BindingSource.DataSource ustawiana jest kolekcja obiektow pobrana z bazydanych lub pliku, przez repozytorium. Interesuje mnie odwzorowanie zmian tylko na tej kolekcji bez odwzorowywania zmian w bazie danych czy plikach (zrodlach z ktorych korzysta repozytorium).

Generalnie chce uzyskac cos takiego.
W DGV wyswietlam pozycje zamowienia, m.in. są tam kolumny (int)Ilość i (bool)CzyDrukowac i tylko te kolumny maja mozliwośc edycji przez uzytkownika. Uzytkownik moze zmienic ilosc i odhaczyc/zaznaczyc checkBoxa okreslajacy czy drukowac zadana ilosc etykiet czy nie.

Przykład jak to powiązałem i ustawiłem.

         public OknoGlowne()
        {
            InitializeComponent();
            presenter = new PresenterOknaGlownego();

            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.DoubleBuffered = true;
            this.presenter.Initialize(this);


            UstawienieStyluDGV_WykazuZamowien();
            dgv_WykazZamowien.DataSource = bSource_WykazZamowien;            
            presenter.UstawZrodloDanychWykazuZamowien();

            UstawienieStyluDGV_WykazuPozycjizamowienia();
            dgv_WykazPozycjiZamowienia.DataSource = bSource_ZaznaczoneZamowienie;
            UstawDaneZaznaczonegoZamowienia();
            WybraneZamowienie = bSource_WykazZamowien.Current as Zamowienie;
        }

        public List<Zamowienie> ListaZamowien
        {
            get
            {
                return this.bSource_WykazZamowien.DataSource as List<Zamowienie>;
            }
            set
            {
                this.bSource_WykazZamowien.DataSource = value;
                this.bSource_WykazZamowien.ResetBindings(false);
            }
        }
        public Zamowienie WybraneZamowienie
        {
            get
            {
                return this.bSource_WykazZamowien.Current as Zamowienie;               
            }
            set
            {
                this.bSource_ZaznaczoneZamowienie.DataSource = ((Zamowienie)value).Pozycje;
                this.bSource_ZaznaczoneZamowienie.ResetBindings(false);
            }
        }

        private void UstawienieStyluDGV_WykazuPozycjizamowienia()
        {
            dgv_WykazPozycjiZamowienia.AutoGenerateColumns = false;
            dgv_WykazPozycjiZamowienia.AlternatingRowsDefaultCellStyle.BackColor = Color.LightCyan;

            dgv_WykazPozycjiZamowienia.Columns.Add("0", "Lp");
            dgv_WykazPozycjiZamowienia.Columns[0].ReadOnly = true;
            dgv_WykazPozycjiZamowienia.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            dgv_WykazPozycjiZamowienia.Columns[0].Width = 40;
            dgv_WykazPozycjiZamowienia.Columns[0].DataPropertyName = "NrPozycji";
            dgv_WykazPozycjiZamowienia.Columns[0].DefaultCellStyle.Font = new Font(dgv_WykazZamowien.Font, FontStyle.Bold);
            dgv_WykazPozycjiZamowienia.Columns[0].Resizable = DataGridViewTriState.False;

            dgv_WykazPozycjiZamowienia.Columns.Add("1", "Index Wyrobu");
            dgv_WykazPozycjiZamowienia.Columns[1].ReadOnly = true;
            dgv_WykazPozycjiZamowienia.Columns[1].Width = 120;
            dgv_WykazPozycjiZamowienia.Columns[1].DataPropertyName = "IndexERP";

            dgv_WykazPozycjiZamowienia.Columns.Add("2", "Nazwa Handlowa");
            dgv_WykazPozycjiZamowienia.Columns[2].ReadOnly = true;
            dgv_WykazPozycjiZamowienia.Columns[2].Width = 238;
            dgv_WykazPozycjiZamowienia.Columns[2].DataPropertyName = "NazwaHandlowa";

            dgv_WykazPozycjiZamowienia.Columns.Add("3", "Nazwa Sprzedażowa");
            dgv_WykazPozycjiZamowienia.Columns[3].ReadOnly = true;
            dgv_WykazPozycjiZamowienia.Columns[3].Width = 238;
            dgv_WykazPozycjiZamowienia.Columns[3].DataPropertyName = "NazwaSprzedazowa";

            dgv_WykazPozycjiZamowienia.Columns.Add("4", "Ilość etykiet");
            dgv_WykazPozycjiZamowienia.Columns[4].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            dgv_WykazPozycjiZamowienia.Columns[4].Width = 50;
            dgv_WykazPozycjiZamowienia.Columns[4].ReadOnly = false;
            dgv_WykazPozycjiZamowienia.Columns[4].DataPropertyName = "Ilosc";

            DataGridViewCheckBoxColumn column = new DataGridViewCheckBoxColumn();
            column.Name = "Wydruk";
            column.Width = 65;
            column.DataPropertyName = "CzyDrukowac";
            column.ReadOnly = false;
            dgv_WykazPozycjiZamowienia.Columns.Add(column);
        }
0

Jeżeli chcesz aby po zmianie na liście w kodzie były widoczne w DGV musisz zaimplementować INotifyProperty.

0

Nie do końca rozumiem ale załóżmy że mamy dwa DGV jeden z listą np. etykiet i drugi DGV z listą etykiet do druku z pierwszego DGV wybieram dane do drugiego poprzez zaznaczenie checkbox'a drukuj. Taki jest zamysł mniej więcej?

0

Pierwszy DGV wyswietla zamówienia, zamówienie składa sie m.in. z sygnatury, numeru, daty zalozenia, kontrahenta(kto zamawia) i listy pozycji(wyrobow) w zamowieniu.
Drugi DGV wyswietla liste pozycji zamowienia, zaznaczonego w pierwszym DGV.

W tym drugim DGV sa m.in. kolumny nazwa wyrobu, ilosc wyrobów w danej pozycji, i checkbox (domyslnie zaznaczony dla wszystkich wyrobów o jednostce rozliczeniowej szt.) oznaczajacy czy drukowac czy nie.

Program na podstawie wyników wyswietlanych w drugim DGV, drukuje na Zebrze etykiety dla kazdego pakowanego wyrobu, umieszczajac tam miedzy innymi dane: nr zamowienia, nazwa wyrobu, kolejna sztuka z danej pozycji zamowienia itp.

Dodatkowo osoba ktora drukuje i pakuje wyroby wg. zamowien, chce miec mozliwosc edycji ilosci w poszczegolnych pozycjach zamowienia, chodzi o reczne dodanie 1szt danego wyrobu w ktorejs pozycji jako np. promocja ewentualnie jako jeszcze cos innego. a checkboxy sluza do tego aby pracownik ktory drukuje etykiety/pakuje wyroby mogla drukowac zamowienie czesciami, tylko te pozycje ktore ma fizycznie na magazynie.

PS. Dodalem calosc stylu drugiego DGV w pierwszym poscie.

0

I chcesz wiedzieć które pozycje zostały zmodyfikowane i porównać to z kolekcją właściwą? Więc do daj CellEndEdit Event do drugiego DGV. I tam dodawaj zmodyfikowane rekordy do nowej kolekcji później możesz je porównać z danymi wcześniej pobranymi.

      private void DGVWyboru_CellEndEdit(object sender, DataGridViewCellEventArgs e)
      {
         var element = DGVWyboru.Rows[e.RowIndex].DataBoundItem as Foo;
         if (element != null && !ZmienioneElementy.Contains(element))
            ZmienioneElementy.Add(element);
         // A jak isnieje to zaktualizuj...
         // ...
      }

</del>

Czyli tak:

// Zmienne
private readonly BindingSource _source = new BindingSource();
private readonly BindingList<Foo> _foos;
// Init
DGV.DataSource = _foos;
_source.DataSource = _foos;

Kolekcja będzie się zmieniać w przypadku zmiany po stronie GUI. Jak zmieniasz coś po stronie kodu to muszisz po zmiane dać:

_source.ResetBindings(false); // false jak struktura się nie zmieniła tylko kolekcja true jak zmieni się struktura.
0

wywolalem ten ResetBindings(false) przed utworzeniem polecenia drukowania, ale nie działa, nadal nie odwzorowało zmian w DGV w kolekcji.

0

Hmm, powinno działać. Zresztą przetestuj to na nowym projekcie na jakimś banalnym przykładzie może coś zrobiłeś nie tak. :P Bo teraz to już mi się pomysły skończyły. ;)

0

załamka, wszystko działa od początku jak trzeba.

Zle sprawdzalem, odhaczalem w dgv checboxy i sprawdzalem tylko czy w zadaniu drukowania zostaja drukowane tylko te pozycje co zostaly odhaczone. Ale w klasie ktora buduje zadanie drukowanie nie sprawdzalem pola CzyDrukowac.

Po prostu załamka, ponizej wklejam karnie prosty kod do sprawdzania dzialania bindowania dla potomnych:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Test_DGV_Bindowanie_2kierunkowe
{
    public partial class Form1 : Form
    {
        private List<PozycjaZamowienia> kolekcja;

        public Form1()
        {
            InitializeComponent();

            kolekcja = new List<PozycjaZamowienia>();
            this.ZapelnijKolekcje();

            bindingSource1.DataSource = kolekcja;
            this.UstawDGV();
            dataGridView1.DataSource = bindingSource1;
        }

        private void ZapelnijKolekcje()
        {
            kolekcja.Add(new PozycjaZamowienia() { ID = 1, Nazwa = "Nazwa 1", Ilosc = 100 });
            kolekcja.Add(new PozycjaZamowienia() { ID = 2, Nazwa = "Nazwa 2", Ilosc = 100 });
            kolekcja.Add(new PozycjaZamowienia() { ID = 3, Nazwa = "Nazwa 3", Ilosc = 100 });
            kolekcja.Add(new PozycjaZamowienia() { ID = 4, Nazwa = "Nazwa 4", Ilosc = 100 });
            kolekcja.Add(new PozycjaZamowienia() { ID = 5, Nazwa = "Nazwa 5", Ilosc = 100 });
            kolekcja.Add(new PozycjaZamowienia() { ID = 6, Nazwa = "Nazwa 6", Ilosc = 100 });
        }

        private void UstawDGV()
        {
            dataGridView1.AutoGenerateColumns = false;
            dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.LightCyan;

            dataGridView1.Columns.Add("0", "Id");
            dataGridView1.Columns[0].ReadOnly = true;
            dataGridView1.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            dataGridView1.Columns[0].Width = 40;
            dataGridView1.Columns[0].DataPropertyName = "ID";
            dataGridView1.Columns[0].DefaultCellStyle.Font = new Font(dataGridView1.Font, FontStyle.Bold);
            dataGridView1.Columns[0].Resizable = DataGridViewTriState.False;

            dataGridView1.Columns.Add("1", "Nazwa Wyrobu");
            dataGridView1.Columns[1].ReadOnly = true;
            dataGridView1.Columns[1].Width = 120;
            dataGridView1.Columns[1].DataPropertyName = "Nazwa";


            dataGridView1.Columns.Add("4", "Ilość etykiet");
            dataGridView1.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            dataGridView1.Columns[2].Width = 50;
            dataGridView1.Columns[2].ReadOnly = false;
            dataGridView1.Columns[2].DataPropertyName = "Ilosc";

            DataGridViewCheckBoxColumn column = new DataGridViewCheckBoxColumn();
            column.Name = "Wydruk";
            column.Width = 65;
            column.DataPropertyName = "CzyDrukowac";
            column.ReadOnly = false;
            dataGridView1.Columns.Add(column);
        }

        private void WyswietlkolekcjeWListBox()
        {
            listBox1.Items.Clear();

            foreach (var item in kolekcja)
            {
                listBox1.Items.Add(item);
            }

        }

        private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            WyswietlkolekcjeWListBox();
        }
    }

    public class PozycjaZamowienia
    {
        public int ID { get; set; }
        public string Nazwa { get; set; }
        public int Ilosc { get; set; }
        public bool CzyDrukowac { get; set; }

        public override string ToString()
        {
            return ID.ToString() + " " + Nazwa + " " + Ilosc.ToString() + "  CzyDrukować?: " + CzyDrukowac.ToString();
        }
    }
}
 

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