Avatar
Michaal.K
Člen
Avatar
Michaal.K:

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. března 17:10
Avatar
Tomáš Brůna
Redaktor
Avatar
Odpovídá na Michaal.K
Tomáš Brůna:

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. března 17:53
Nahoru Odpovědět 10. března 17:52
Lepší být šprt než blbec :)
Avatar
Odpovídá na Michaal.K
Petr Čech (czubehead):

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. března 19:55
Nahoru Odpovědět 10. března 19:53
Why so serious? -Joker
Avatar
Michaal.K
Člen
Avatar
Odpovídá na Petr Čech (czubehead)
Michaal.K:

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. března 13:46
Avatar
Odpovídá na Michaal.K
Petr Čech (czubehead):

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í
+1 bodů
Řešení problému
Nahoru Odpovědět 11. března 16:32
Why so serious? -Joker
Avatar
Michaal.K
Člen
Avatar
Odpovídá na Petr Čech (czubehead)
Michaal.K:

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. března 8:07
Avatar
Michaal.K
Člen
Avatar
Odpovídá na Petr Čech (czubehead)
Michaal.K:

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  +1 14. března 8:19
Avatar
Odpovídá na Michaal.K
Petr Čech (czubehead):

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

Nahoru Odpovědět 14. března 15:42
Why so serious? -Joker
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.