Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Michaal.K
Člen
Avatar
Michaal.K:10.3.2016 17:10

Ahoj,
potřeboval bych poradit s generováním nových komponent z kódu. Chtěl bych mít okno settings pro nastavení parametrů několika sériových portů, kde by bylo z kódu vygenerovano tabcontrol ve kterém by byly komponenty combobox (pro nastavení rychlosti, parity a stop bitu, případně další...). Zkusil jsem to takto viz. kód níže.
Nebo to lze generovat jednodušeji, bez použití TableLayoutPanel a GroupBox????
Takto se mi vygeneruje v každé záložce combobox, to je fajn, ale teď bych potřeboval po stisku nějakého tlačítka OK ze všech záložek tabcontrol přečíst aktuálně nastavené hodnoty uživatelem a ty uložit do listu. A já nevím jak se na ty jednotlivé comboboxy dotazovat...

public Form1()
        {
            InitializeComponent();

            for (int i = 0; i < 5; i++)
            {
                ComboBox cbSpeed = new ComboBox();
                cbSpeed.Name = "COM" + i;
                cbSpeed.Items.Add("2400");
                cbSpeed.Items.Add("4800");
                cbSpeed.Items.Add("9600");
                cbSpeed.Items.Add("19200");
                cbSpeed.DropDownStyle = ComboBoxStyle.DropDownList;
                cbSpeed.SelectedIndex = 0;

                TableLayoutPanel tlp = new TableLayoutPanel();
                tlp.Dock = DockStyle.Fill;
                tlp.RowCount = 1;
                tlp.ColumnCount = 2;
                tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
                tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent));
                tlp.Controls.Add(cbSpeed);

                tlp.BackColor = Color.Green;

                GroupBox gb = new GroupBox();
                gb.Text = "Apply Renderers";
                gb.Dock = DockStyle.Fill;
                gb.Controls.Add(tlp);

                string title = "COM" + i;
                TabPage myTabPage = new TabPage(title);
                tabControl1.TabPages.Add(myTabPage);

                tabControl1.TabPages[i].Controls.Add(gb);

            }

        }

Díky za rady :-)

 
Odpovědět
10.3.2016 17:10
Avatar
Tomáš Brůna
Tvůrce
Avatar
Odpovídá na Michaal.K
Tomáš Brůna:10.3.2016 17:52

http://www.itnetwork.cz/…indows-forms
a na přidávání kontrolek používám:

Controls.add(kontrolka);

ale nevím jestli jsem tě správně pochopil

Editováno 10.3.2016 17:53
Nahoru Odpovědět
10.3.2016 17:52
Vi veri universum vivus vici
Avatar
Petr Čech
Tvůrce
Avatar
Odpovídá na Michaal.K
Petr Čech:10.3.2016 19:53

uděláš si metodu (ve formu)

private static IEnumerable<T> GetChildrenOfType<T>(Control parent) where T : Control
        {
            foreach (var control in parent.Controls)
            {
                if (control is T)
                {
                    yield return control as T;
                }
            }
        }

která se dá pomocí LINQ zkrátit na:

private static IEnumerable<T> GetChildrenOfType<T>(Control parent) where T:Control
        {
            return parent.Controls.Cast<Control>().Where(c => c is T).Cast<T>().ToList();
        }

Dělá to úplně to samé. Pokud tomu nerozumíš, buď to ber jako blackbox, nebo si nastuduj generiku a LINQ.
A použiješ to takto:

List<ComboBox> boxes = GetChildrenOfType<ComboBox>(tabControl1.TabPages[i]).ToList();//všechny comboboxy, co jsou přímo obsažené v TabPage

Jinak pokud se ptáš, proč vracím IEnumerable a ne List, dalo by se říct, že jde víceméně o konvenci.
Metody jsou statické kvůli tomu, že nepracují s instančními proměnnými, proto je vhodné je označit jako statické kvůli čitelnosti kódu ;-)

Editováno 10.3.2016 19:55
Nahoru Odpovědět
10.3.2016 19:53
the cake is a lie
Avatar
Michaal.K
Člen
Avatar
Odpovídá na Petr Čech
Michaal.K:11.3.2016 13:46

Ahoj, díky za odpověď.
Kód moc nechápu :-( Nešlo by to udělat jednodušeji?? Potřebuji z každého comboboxu ze všech záložek tabcontrol uložit do nějakého listu hodnotu SelectedItem...
Jinak mi to moc nefunguje. Použil jsem to takhle, viz. kód níže. Dotoho listu boxes se sice uloží combobox (a jeho všechny parametry, jestli jsem to dobře pohopil), ale při dalším průběhu cyklu se mi hodnota přepíše, nemělo by tam být Add()?

private static IEnumerable<T> GetChildrenOfType<T>(Control parent) where T : Control
        {
            foreach (var control in parent.Controls)
            {
                if (control is T)
                {
                    yield return control as T;
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            for(int i = 0; i < tabControl1.TabPages.Count ; i++)
            {
                List<ComboBox> boxes = GetChildrenOfType<ComboBox>(tabControl1.TabPages[i]).ToList();   //všechny comboboxy, co jsou přímo obsažené v TabPage
            }
        }
 
Nahoru Odpovědět
11.3.2016 13:46
Avatar
Petr Čech
Tvůrce
Avatar
Odpovídá na Michaal.K
Petr Čech:11.3.2016 16:32

Možná bych měl trochu lépe vysvětlit, co ten kód dělá. Předáš mu kontrolku, ve které jsou obsažené ty comboboxy.
To, co jsem napsal je univerzální, dá se to použít třeba na tlačítka panely, všechno. Proto to používá generiku- vše ohledně T a <T>
Pokud bych tu metodu přepsal bez generiky čistě pro comboboxy a zjednodušil, vypadala by takto:

private static List<Combobox> GetComboBoxes(Control parent)
{
        List<Combobox> result=new List<Combobox>();
        foreach (var control in parent.Controls)
        {
                if (control is Combobox)
                {
                        result.Add(control as Combobox);
                }
        }
        result result;
}

A použiješ ji takto:

List<Combobox> allCombos=new List<Combobox>(); //sem se načtou všechny comboboxy ze všech TabPage
foreach (var tab in tabControl1.TabPages)
{
        allCombos.AddRange(GetComboBoxes(tab));//načíst všechny, co jsou v dané tabPage
}

potom budeš mít v allCombos všechny comboboxy, které jsou obsažené v "tabech" tabControl1. Potom to jen projedeš třeba foreach cyklem, kde si zjistíš u každého comboboxu SelectedItem.
Pokud tohle není co chceš, zkus se vyjádřit nějak lépe, možná jsem tě nepochopil.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
11.3.2016 16:32
the cake is a lie
Avatar
Michaal.K
Člen
Avatar
Odpovídá na Petr Čech
Michaal.K:14.3.2016 8:07

Ahoj, díky za zjednodušení. Teď už je mi to srozumitelnější...
Jen teď když volám metodu: allCombos.AddRan­ge(GetComboBo­xes(tab));
tak mi toho vyhodí při kompilaci error: Argument 1: cannot convert from 'object' to 'System.Window­s.Forms.Control' a nevím jak to přesně přetypovat.

 
Nahoru Odpovědět
14.3.2016 8:07
Avatar
Michaal.K
Člen
Avatar
Odpovídá na Petr Čech
Michaal.K:14.3.2016 8:19

Tak se mi to podařilo přetypovat a vypadá to, že to funguje :-)

allCombos.AddRange(GetComboBoxes((Control) tab));//načíst všechny, co jsou v dané tabPage
 
Nahoru Odpovědět
14.3.2016 8:19
Avatar
Petr Čech
Tvůrce
Avatar
Odpovídá na Michaal.K
Petr Čech:14.3.2016 15:42

Označ potom prosím moje řešení :-)

Nahoru Odpovědět
14.3.2016 15:42
the cake is a lie
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.