• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

c# Jak przenieść listę obietków <dynamic> pomiędzy dwoma formularzami

Object Storage Arubacloud
0 głosów
348 wizyt
pytanie zadane 2 stycznia 2021 w C# przez j.cob_21 Początkujący (350 p.)

Cześć,
W C# jestem praktycznie zielony i mam olbrzymi wręcz nie do przeskoczenia problem z podaniem listy obiektów list_of_done_items do drugiego formularza o nazwie warehouse_usercontrol.
Lista list_of_done_items jest tworzona dynamicznie podczas działania aplikacji w kontrolce użytkownika production_usercontrol. Lista ta zawiera obiekty które mają dwa atrybuty string type oraz int quantity więc przekazywanie samych zmiennych odpada...

Szukałem godzinami próbowałem różnych metod działania ale nic mi nie wychodzi i nie wiem czy się po prostu nie poddać.

Na razie stanąłem na tym, że w kodzie warehouse_usercontrol napisałem 

production_usercontrol h = new production_usercontrol();

I to w zasadzie tyle, jak próbuję wywołać listę za pomocą h.list_of_done_items to jest ona pusta.

W związku z tym, że jest ona dynamicznie tworzona podczas dzialania aplikacji chciałem ten "instance" odświerzać w private void timer_tick ale to również nie działa.
Co mam tu zrobić bo już mi nadzieja ucieka, że sobie w ogóle z tym poradzę....

komentarz 2 stycznia 2021 przez adrian17 Ekspert (344,860 p.)
Nie za bardzo rozumiem. W szczególności dlaczego potrzebujesz <dynamic>.

Możesz proszę pokazać więcej kodu jako kontekst?
komentarz 2 stycznia 2021 przez j.cob_21 Początkujący (350 p.)
Dobrze, zaraz wrzucę kod poniżej.

1 odpowiedź

0 głosów
odpowiedź 2 stycznia 2021 przez j.cob_21 Początkujący (350 p.)

Tutaj wrzucam kod:

Implementacja klasy production_ordered w kontrolce użytkownika production_usercontrol:

public partial class Production_usercontrol : UserControl
    {
        
        public Production_usercontrol()
        {
            InitializeComponent();
            Prd_timer.Start();
            Control_timer.Start();
            
        }
        //##################################################################
       
        public class production_ordered
        {
            public int production_time_obj; // A
            public int par_quan; // B
            public int lin_quan; //C
            public string type; //D
            public int ID_prd;
            public int tick_start;
            public string status;
            public int cost;

            public void Ordered_prd(int A, int B, int C, string D, int ID, int prd_tick_start_val, string prd_status, int cost)
            {
                
                this.production_time_obj = A;
                this.par_quan = B;
                this.lin_quan = C;
                this.type = D;
                this.ID_prd = ID;
                this.tick_start = prd_tick_start_val;
                this.status = prd_status;
                this.cost = cost;
               // MessageBox.Show("Production time: " + this.production_time_obj.ToString() + "\n Parallel quantity: " + this.par_quan.ToString() + "\n Linear quantity: " + this.lin_quan.ToString() + "\n Type: " + this.type.ToString() + "\n ID: " + this.ID_prd.ToString() + "\n Tick start: " + this.tick_start.ToString() );
            }
           
        }

Pobranie wartości stringa z zaznaczonego "ptaszka" checkedlistbox i na jej podstawie określenie wartości atrybutów production_time oraz item_cost:
 

 string checkedItemText;
        int production_time;
        int item_cost;
        private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            var checkedListBox = (CheckedListBox)sender;
            checkedItemText = checkedListBox.Items[e.Index].ToString();
            if (checkedItemText == "111111")
            {
                production_time = 10;
                item_cost = 120;
            } else if (checkedItemText == "222222")
            {
                production_time = 12;
                item_cost=15;
            } else if (checkedItemText == "333333")
            {
                production_time = 6;
                item_cost = 55;
            } else if (checkedItemText == "444444")
            {
                production_time = 8;
                item_cost = 72;
            } else if (checkedItemText == "555555")
            {
                production_time = 9;
                item_cost = 98;
            }
        }


Implementacja listy listy obiektów oraz tworzenie obiektów na kliknięcie przycisku:
 

 public List<dynamic> ordprd = new List<dynamic>();
        int index = 0;
        int id=0;
        int count_control = 1;
        public void button1_Click_1(object sender, EventArgs e)
        {
//#######################################################################################
            int a = production_time;

            bool ol;
            int b;
            ol = int.TryParse(Parallel_quantity.Text, out b );

            bool rec;
            int c;
            rec = int.TryParse(Linear_quantity.Text, out c ) ;


            string d = checkedItemText;
            id++;

            int tck_start_btn = 0;

            string production_status = "inproduction";

            int itemcost = item_cost;

            production_ordered prod= new production_ordered();
            prod.Ordered_prd(a, b, c, d, id, tck_start_btn, production_status, item_cost);

            
            ordprd.Add(prod);
           
            
            

            MessageBox.Show(ordprd[index].type.ToString());
            index++;





            //###########################################################################################


          //tutaj w kodzie jako graficzną interpretację obiektów tworzę dynamicznie kontrolki takie jak groupbox, label itp.
}

Ustawianie wartości w textboxach linear_quantity oraz parallel_quantity - wyżej w kodzie po naciśnięciu przycisku pobierana jest wartość tekstu i zamieniana na int który jest odpowiednim atrybutem klasy production_ordered
 

 int pq = 0;

        
        private void Parallel_plus_Click(object sender, EventArgs e)
        {
            bool res;

            res = int.TryParse(Parallel_quantity.Text, out pq);
            pq++;
            Parallel_quantity.Text = pq.ToString();


        }
        private void Parallel_minus_Click(object sender, EventArgs e)
        {
            bool res;
            int a;
            string pqt = Parallel_quantity.Text;
            res = int.TryParse(pqt, out a);
            a--;
            Parallel_quantity.Text = a.ToString();

        }

        int lq = 0;

        private void Linear_plus_Click(object sender, EventArgs e)
        {
            bool res;

            res = int.TryParse(Linear_quantity.Text, out lq);
            lq++;
            Linear_quantity.Text = lq.ToString();
        }

        private void Linear_minus_Click(object sender, EventArgs e)
        {
            bool res;
            int a;
            string pqt = Linear_quantity.Text;
            res = int.TryParse(pqt, out a);
            a--;
            Linear_quantity.Text = a.ToString();
        }


Implementacja klasy items_done oraz listy list_of_items_done która zawiera wszystkie obiekty klasy items_done.
Klasa items_done dziedziczy atrybut type z klasy production_ordered.

 

public class items_done 
        {
            public string type;
            public int quantity;
            

            public void items_done_fcn(string type, int quantity) 
            {
                this.type = type;
                this.quantity = quantity;
                
            }


        }

        public List<dynamic> list_of_items_done = new List<dynamic>();

        private void Control_timer_Tick(object sender, EventArgs e)
        {
            if (ordprd.Count > 0)
            {
                for (int i = 0; i < ordprd.Count; i++)
                {

                    if((ordprd[i].tick_start < ordprd[i].production_time_obj)&&(ordprd[i].status == "inproduction"))
                    {
                        int control_count;
                        control_count = ordprd[i].tick_start;
                        ordprd[i].tick_start = control_count + 1;
                    }else if((ordprd[i].tick_start == ordprd[i].production_time_obj)&&(ordprd[i].status == "inproduction"))
                    {
                        items_done itm = new items_done();
                        itm.items_done_fcn(ordprd[i].type, 1000);
                        list_of_items_done.Add(itm);

                        ordprd[i].status = "done";

                        if (list_of_items_done.Count > 0)
                        {
                            for (int x = 0; x < list_of_items_done.Count; x++)
                            {
                                MessageBox.Show("Przedmiot: " + list_of_items_done[x].type + "\nIlość: " + list_of_items_done[x].quantity);
                            }
                        }
                    }else if(ordprd[i].status != "inproduction")
                    {

                    }

                }
            }
            else { }
        }



I to jest cały kod kontrolki production_usercontrol
Teraz poniżej wstawię to co napisałem w warehouse_usercontrol.:
 

 public partial class Warehouse_usercontrol : UserControl
    {
        public Warehouse_usercontrol()
        {
            InitializeComponent();
            timer1.Start();
            
        }
        

        List<dynamic> items_list = new List<dynamic>();

        int listlength;
        int ticktest=0;
        public void timer1_Tick(object sender, EventArgs e)
        {
            Production_usercontrol h = new Production_usercontrol();
            listlength = h.list_of_items_done.Count;
            textBox1.Text = listlength.ToString();
           
            if (listlength > 0)
            {
                MessageBox.Show(h.list_of_items_done[ticktest].type);
            }
            ticktest++;

            /*
            ticktest++;
            if((ticktest == 20)&&(h.list_of_items_done.Count > 0))
            {
                textBox1.Text = h.list_of_items_done[0].type;
                MessageBox.Show(h.list_of_items_done[0].type);
            }*/
           // h.list_of_items_done.Add(12);

        }
    }

Napisałem w private void timer_tick taki kod nie dlatego, że on mi faktycznie jest później potrzebny tylko dlatego, żeby sprawdzić czy przekazuję dane z kontrolki production_usercontrol do warehouse_usercontrol
 

komentarz 2 stycznia 2021 przez adrian17 Ekspert (344,860 p.)

Wciąż nie rozumiem, czemu `List<dynamic>`, jak w jednej przechowujesz jedynie `production_ordered`, a w drugiej jedynie `items_done`. (btw, popraw nazewnictwo, klasy CamelCasem).

I tak jak 2 dni temu, wciąż piszesz dziwne metody jak `Ordered_prd` zamiast konstruktorów.

           Production_usercontrol h = new Production_usercontrol();
           listlength = h.list_of_items_done.Count;

ale tutaj zupełnie nic nie przekazujesz, tylko tworzysz zupełnie nową kontrolkę; to nic dzienego, że `list_of_items_done` jest tutaj puste.

Gdzie w ogóle... są te kontrolki? Czy obie są widoczne na raz? Gdzie jest kod konstruujący je?

komentarz 2 stycznia 2021 przez j.cob_21 Początkujący (350 p.)
No dobra to po kolei:
1) List<dynamic> dałem dlatego, że jak dawałem list<int> czy innego typu to nie działało.
2)Odnośnie konstruktorów to nie rozumiem o co Ci chodzi - myślałem, że po prostu metoda zawarta w klasie i wywoływana później jest jej konstruktorem
3)Odnośnie wywoływania "list_of_items_done" to próbowałem ją jakoś zawałoć ale kompletnie nie wiem jak - po prostu tego nie rozumiem.
4)Kontrolki są zaprojektowane odgórnie - są one umieszczone w Form1.cs[projekt] jako no zwykład "aplikacja" która chodzi w tle.
Są one chowane i pokazywane za pomocą metod .Hide i .Show po naciśnięciu konkretnego przycisku.
komentarz 2 stycznia 2021 przez adrian17 Ekspert (344,860 p.)

jak dawałem list<int> czy innego typu to nie działało.

No bo lista ordprd nie przechowuje intów, tylko obiekty typu `production_ordered`.

Odnośnie konstruktorów to nie rozumiem o co Ci chodzi - myślałem, że po prostu metoda zawarta w klasie i wywoływana później jest jej konstruktorem

Nie, kontruktor to metoda o tej samej nazwie co klasa, automatycznie wywoływana przy robieniu `new`.

To jest konstruktor i jego wywołanie:

class C {
  public int wiek;
  public C(int wiek) { this.wiek = wiek; }
}
...
C c = new C(5);

A to nie:

class C {
  public int wiek;
  public void costam(int wiek) { this.wiek = wiek; }
}
...
C c = new C();
c.costam(5);

Kontrolki są zaprojektowane odgórnie - są one umieszczone w Form1.cs[projekt] jako no zwykład "aplikacja" która chodzi w tle.

Tak, ale są wtedy reprezentowane jako pola klasy Form1. Masz w Form1 pole typu `Production_usercontrol` które zawiera wypełnioną zawartość `list_of_items_done`.

komentarz 2 stycznia 2021 przez j.cob_21 Początkujący (350 p.)

No dobra to te pierwsze kilka rzeczy rozumiem.
Natomiast jeśli chodzi o to:

Tak, ale są wtedy reprezentowane jako pola klasy Form1. Masz w Form1 pole typu `Production_usercontrol` które zawiera wypełnioną zawartość `list_of_items_done`.

To co proponujesz? Bo jak próbowałem się do tego dostać w taki sposób:
production_usercontrol.list_of_items_done lub też Form1.list_of_items_done (już nie pamiętam dokładnie jak to było) to mi wyrzucało błąd, że obiekt jest niedostępny z powodu swojego poziomu ochrony - więc porzuciłem tego typu podejście i dlatego też nie pamiętam już jak to dokładnie napisałem...

komentarz 2 stycznia 2021 przez adrian17 Ekspert (344,860 p.)
no, jeśli zrobiłeś te listy prywatnymi, to nic dziwnego.

W każdym razie Form1 musi pełnić tutaj rolę pośredniczącą, bo to on zawiera obie kontrolki między którymi chcesz przenieść dane. Możesz np w Form1 przekazać to pole z jednej kontrolki do drugiej jako referencję, albo przekazać całą referencję na kontrolkę #1 do kontrolki #2, albo wywołać metodę na kontrolce #1 przekazując jako argument kontrolkę #2, etc.

Proponuję poguglować, bo o temacie przekazywania danych między kontrolkami sporo się pisze.

Podobne pytania

0 głosów
1 odpowiedź 1,107 wizyt
+1 głos
2 odpowiedzi 122 wizyt
pytanie zadane 8 lipca 2023 w C# przez xFrikeQ Nowicjusz (130 p.)
+1 głos
2 odpowiedzi 368 wizyt
pytanie zadane 26 października 2021 w C# przez Kamio Obywatel (1,100 p.)

92,551 zapytań

141,393 odpowiedzi

319,522 komentarzy

61,936 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...