• 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

Hosting forpsi easy 1 pln
0 głosów
275 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 (336,700 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 (336,700 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 (336,700 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 (336,700 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ź 994 wizyt
+1 głos
2 odpowiedzi 98 wizyt
pytanie zadane 8 lipca w C# przez xFrikeQ Nowicjusz (130 p.)
+1 głos
2 odpowiedzi 277 wizyt
pytanie zadane 26 października 2021 w C# przez kamil_K Obywatel (1,160 p.)

92,105 zapytań

140,763 odpowiedzi

317,744 komentarzy

61,424 pasjonatów

Advent of Code 2023

Top 15 użytkowników

  1. 590p. - Łukasz Eckert
  2. 584p. - Dawid128
  3. 575p. - CC PL
  4. 571p. - TheLukaszNs
  5. 552p. - nidomika
  6. 546p. - Michal Drewniak
  7. 544p. - Mikbac
  8. 539p. - Eryk Andrzejewski
  9. 537p. - 13NOONE37
  10. 536p. - Arkadiusz Waluk
  11. 533p. - Henry Saele
  12. 525p. - sefirek
  13. 522p. - adrian17
  14. 514p. - rucin93
  15. 505p. - Adrian Wieprzkowicz
Szczegóły i pełne wyniki

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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...