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
tomas
Člen
Avatar
tomas:11.6.2013 17:34

Ahoj všem. Mám problém s načtení textboxů z formuláře. Mám následující kód.

private void tlZapsatZmeny_Click(object sender, EventArgs e)
{

    foreach (Control c in controls)
    {

        if (c.GetType() is TextBox)
        {
            ......
        }
    }
}

Potřebuju zjistit obsah všech textboxů z formuláře. Problém je v tom, že mám ve formuláři splitContainer a tento kód mě vrací pouze jeden control prvek a tím je právě ten splitcontainer.

 
Odpovědět
11.6.2013 17:34
Avatar
Neaktivní uživatel:11.6.2013 17:49

v texBoxu je text - string, takže můžeš napsat třeba:

string s = texBox1.Text

a následne s obsahem každého textboxu pracovat jako se stringem (např. zkoušet parsovat a zjistit, jestli se nejedná o číslo, atd.)

Nahoru Odpovědět
11.6.2013 17:49
Neaktivní uživatelský účet
Avatar
Odpovídá na tomas
Neaktivní uživatel:11.6.2013 18:18

Aha, už sem asi pochopil tvůj problém:

foreach (Control c in controls)
{

    if (c is TextBox)
    {

        string s = c.Text;
        listString.Add(c.Text);
    }
}
Nahoru Odpovědět
11.6.2013 18:18
Neaktivní uživatelský účet
Avatar
tomas
Člen
Avatar
Odpovídá na Neaktivní uživatel
tomas:11.6.2013 19:52

No nepochopil :), můj problem je v tom, že cyklus foreach (Control c in controls) projde jenom jednou. Protože v controls je jenom jeden objekt, a to je System.Window­s.Forms.Split­Container. A tento objekt má dva kontejnery. Jeden obsahuje datagrid a druhy obsahuje TabControl s dvěma záložkami. Na jedné z nich je 7 TextBoxů, 2 tlačítka, 2 chackBoxy a 7 labelů. Tudíš ta podmínka nikdy nebude splněna. Přímej přístup k tomu textboxu mám. TextBox1.text mě funguje. Ale já obsah porovnávám s původní hodnotou a posílám do DB. Lze to pro každé pole udělat sólo, ale já chci v tom cyklu projít všechny pole a udělat na nich stejné operace. Jen nevím jak se k tomu TexBoxu v tom cyklu dostat.

 
Nahoru Odpovědět
11.6.2013 19:52
Avatar
Odpovídá na tomas
Neaktivní uživatel:11.6.2013 20:19

Hm... ono taky dost záleží na tom, jak/kde máš definované controls (+ jsi si jistý, že controls obsahuje System.Window­s.Forms.Split­Container a ne např. splitcontainer1? Kdybys definoval controls jako List<Control> a přidal do něj všechny prvky (např. textBox1, textBox2, splitContainer1­...), tak ti kód bude běhat, jak má.

Nahoru Odpovědět
11.6.2013 20:19
Neaktivní uživatelský účet
Avatar
Odpovídá na tomas
Luboš Běhounek Satik:11.6.2013 20:32

Budeš muset asi projet všechny controly rekurzivně.

Třeba nějak takhle (psáno od oka, nezkoušel jsem to):

Stack<Control> stack = new Stack();
List<TextBox> textboxy = new List<TextBox>();

foreach (Control c in this.Controls)
    stack.Push(c);

while (stack.Count>0)
{
    Control c = stack.Pop();
    if (c is TextBox)
    {
        textboxy.Add(c);
    }

    foreach (Control c2 in c.Controls)
        stack.Push(c2);
}
Nahoru Odpovědět
11.6.2013 20:32
https://www.facebook.com/peasantsandcastles/
Avatar
tomas
Člen
Avatar
Odpovídá na Neaktivní uživatel
tomas:12.6.2013 11:20

No abych pravdu řekl, tak jsem tento způsob načtení našel v knížce. Textbox jsem definoval v design režimu ve visualstudiu. A jsem si jistý, že to vrátí SplitContainer. Všechny prvky(label, texbox, button, ..) jsou definovaný v privátní metodě InitializeCom­ponent(). Jako příklad uvedu jeden textbox.

this.poleJmeno = new System.Windows.Forms.TextBox();

A potom metoda obsahuje i přidání jednotlivých prvků do controls.

this.grpZmenaUzivatele.Controls.Add(this.lblJmeno);

Jakže předpokládám, že jsou všechny prvky v controls obsaženy.

 
Nahoru Odpovědět
12.6.2013 11:20
Avatar
tomas
Člen
Avatar
Odpovídá na tomas
tomas:12.6.2013 11:26

už jsem na to asi přišel. Mám celej formulář obalený v groupBoxu a on mě přidává všechny prvky do controls toho groupBoxu, když jsem ten grbzmenaUzivatele odmázl, měl jsem ten prvek již dostupný. Jdu to ještě o testovat.

 
Nahoru Odpovědět
12.6.2013 11:26
Avatar
Odpovídá na tomas
Neaktivní uživatel:12.6.2013 13:37

že ty prvky jsou definovaný v InitializeCom­ponent() vim - dej si ve VS Go To Definition poleJmeno... :)

Je rozdíl, jestli napíšeš Controls (kolekce control prvků) a controls (to co si sám nadefinuješ, například i jako kolekce List<Control>, případně jinak - pokud to má pro tebe smysl).

Doporučuju zkusit pro různé prvky (s patričnou úpravou):

foreach (Control c in this.Controls)
{
    if (c == this.textBox1)
        MessageBox.Show("Jsem textBox1!", "zprava",MessageBoxButtons.OK);
}
Nahoru Odpovědět
12.6.2013 13:37
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Luboš Běhounek Satik:12.6.2013 13:43

To dělá ten můj kód výše, projede všechny controly na formu a všechny controly těch controlů a všechny controly controlů těch controlů... :)

A textboxy uloží do listu

Nahoru Odpovědět
12.6.2013 13:43
https://www.facebook.com/peasantsandcastles/
Avatar
Odpovídá na Luboš Běhounek Satik
Neaktivní uživatel:12.6.2013 14:00

To ano, já ale narážel na něco jiného :`

Nahoru Odpovědět
12.6.2013 14:00
Neaktivní uživatelský účet
Avatar
tomas
Člen
Avatar
Odpovídá na Neaktivní uživatel
tomas:12.6.2013 15:23

Ten tvůj kód mě nepomůže. A v mém případě je nesmyslný. Je nesmysl porovnavat promenou s konkrétním textboxem. Já se k tomu textboxu dostanu přímo takle.

string obsahPole = poleJmeno.ToString();

Tvoje podmínka je proto nesmyslná, a nebude nikdy pravda, protože cyklus projde jenom jednou s následujícím výsledkem

c = System.Windows.Forms.SplitContainer

Chápeš? No vyřešil jsem to úpravou souboru .desinger.cs. Není to ale korektní řešení, protože jak udělám jakoukoliv změnu ve vizuání části, tak se mě to pole smaže.

private System.Collections.Generic.List<System.Windows.Forms.TextBox> seznamTextBox;

seznamTextBox = new System.Collections.Generic.List<System.Windows.Forms.TextBox>();
this.seznamTextBox.Add(this.poleJmeno);
this.seznamTextBox.Add(this.polePrijmeni);

No a teď už mám všechny pole v jediným seznamu.

foreach (Control c in seznamTextBox)
{
   // pri prvnim pruchodu obsahuje promena c první objekt textbox poleJmeno
   string sloupec = c.Tag.ToString();
   string hodnota = c.Text.ToString();
   metodaUlozDoDB(sloupec, hodnota, puvodniHodnota);
}

Rozumíme si? Co potřebuju? Nevím jestli to dobře vysvětluju.

 
Nahoru Odpovědět
12.6.2013 15:23
Avatar
tomas
Člen
Avatar
tomas:12.6.2013 15:30

Teď koukám že to pole můžu definovat i jinde, nemusí to být v tom desinger.cs. Ale pořád je to pole které musím vytvořit. Myslel jsem si, že můžu načíst ty textboxy přímo, bez ukládání do nějakého pole. Ale tak jak jsem to myslel to asi nejde. Takže abych toho docílil, tak prostě musím znát název toho textBoxu. Prostě nejde vybrat všechny prvky na formuláři a projít si je s podmínkou, že jestli je prvek textbox, udělej akci.

 
Nahoru Odpovědět
12.6.2013 15:30
Avatar
Odpovídá na tomas
Luboš Běhounek Satik:12.6.2013 15:35

Nečetl jsi můj příspěvek? :)
Ten kód proleze všechny Controly na formu a do listu ti vybere jen textboxy, takže pak už jen proiteruješ výsledné textboxy.

Editováno 12.6.2013 15:36
Nahoru Odpovědět
12.6.2013 15:35
https://www.facebook.com/peasantsandcastles/
Avatar
tomas
Člen
Avatar
tomas:12.6.2013 15:42

Ha, tak jsem na to přišel. Jsem idiot, byla to blbost. Všem se omlouvám, ale mějte se mnou slitování, teprve do tajů c-sharpu pronikám. následující kód mě funguje tak jak má. Já psal podmínku pro cyklus špatně. Popel na moji hlavu.

foreach (Control c in grpZmenaUzivatele.Controls)
{
    if (c is TextBox)
    {
        string sloupec = c.Tag.ToString();
        string hodnota = c.Text.ToString();

    }
}

Jinak děkuju za snahu, vážím si jí. Díky!

Editováno 12.6.2013 15:42
 
Nahoru Odpovědět
12.6.2013 15:42
Avatar
tomas
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
tomas:12.6.2013 15:45

Díval a neproleze :), this.Controls vrací jen ten SplitContainer. Řešení jsem už napsal. Asi mu vadí, že mám textboxy uvnitř jiného prvku.

 
Nahoru Odpovědět
12.6.2013 15:45
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na tomas
Domiy:12.6.2013 15:58

Proboha! typeof ti nic neříká?

 
Nahoru Odpovědět
12.6.2013 15:58
Avatar
Odpovídá na tomas
Luboš Běhounek Satik:12.6.2013 16:01

Ale nezkoušel jsi to, jen sis řekl, že to nebude fungovat :)
SplitContainer je totiž potomek Controlu, takže by to fungovalo ;)

Nahoru Odpovědět
12.6.2013 16:01
https://www.facebook.com/peasantsandcastles/
Avatar
Odpovídá na tomas
Neaktivní uživatel:12.6.2013 16:08
string obsahPole = poleJmeno.ToString();
  • takto nezjistíš obsah pole/prvku, ale Třídu prvku.

Udělej si nový formulář, kde si uděláš textBox1 a zkus ten code.
(mimochodem c.Text je dycky string, takže to ToString() tam nemusí být).

Hlavně, že ti to už chodí :)

Nahoru Odpovědět
12.6.2013 16:08
Neaktivní uživatelský účet
Avatar
tomas
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
tomas:12.6.2013 16:28

Ale já to zkousel, jenže jsem narazil na stejnej problém. Ten cyklus prošel jen jednou a vrátil ten kontejner. Ale je fakt, že jsem zkusil jen ten cyklus a když jsem viděl že to vrací jen ten kontejner, tak jsem to dál neřešil. Teď ale koukám, že tam máš další cyklus kterej ten kontejner prochází, takže by to asi taky fungovalo.

 
Nahoru Odpovědět
12.6.2013 16:28
Avatar
tomas
Člen
Avatar
Odpovídá na
tomas:12.6.2013 16:29

Nechápu jak to myslíš. V čem je rozdíl mezi typeof a is? Doberu se ke stejnému výsledku.

 
Nahoru Odpovědět
12.6.2013 16:29
Avatar
Kit
Tvůrce
Avatar
Odpovídá na tomas
Kit:12.6.2013 16:38

Ne tak docela. Tohle mi našel Google:

if (obj is ClassA) {}
if (obj.GetType() == typeof(ClassA)) {}

is tells you if the object implements ClassA anywhere in its type heirarchy. GetType() tells you about the most-derived type.

Jinými slovy: is proleze celý strom dědičnosti. Pokud nalezne shodu, dá výsledek true. typeof() jen poskytne název třídy. Každý zápis je tedy vhodný k jinému účelu.

Nahoru Odpovědět
12.6.2013 16:38
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
tomas
Člen
Avatar
Odpovídá na Kit
tomas:12.6.2013 16:46

Aha, tak je mě to jasný. Dík.

 
Nahoru Odpovědět
12.6.2013 16:46
Avatar
Odpovídá na tomas
Luboš Běhounek Satik:12.6.2013 17:04

Teď koukám, že ten můj kód by byl zbytečně složitý, nevšiml jsem si, že Form také dědí od Control :)

Stack<Control> stack = new Stack();
List<TextBox> textboxy = new List<TextBox>();

stack.Push(this);

while (stack.Count>0)
{
    Control c = stack.Pop();
    if (c is TextBox)
    {
        textboxy.Add(c);
    }

    foreach (Control c2 in c.Controls)
        stack.Push(c2);
}
Nahoru Odpovědět
12.6.2013 17:04
https://www.facebook.com/peasantsandcastles/
Avatar
Jan Vargovský
Tvůrce
Avatar
Jan Vargovský:12.6.2013 17:44

Nějak moc jsem to tu nečetl, ale jestli chceš proiterovat všechny prvky v tom containeru, tak ten se skládá z jednotlivých panelu a ten panel už tam potom obsahuje ty controls. takže na příkladu takto:

foreach (Control c in splitContainer1.Panel1.Controls)
            {
                if (c is Label)
                    MessageBox.Show(c.Text);
            }

Zkusím ještě prozkoumat jestli by nešlo proiterovat ty panely v containeru a pak v nich iterovat ty controly

 
Nahoru Odpovědět
12.6.2013 17:44
Avatar
Jan Vargovský
Tvůrce
Avatar
Jan Vargovský:12.6.2013 17:49

Tak jsem se na ten control blíž podíval a je tam fixla velikost na 2 panely, takže jestli to máš narvané v obou, tak musíš proiterovat obadva pod sebou(první ten Panel1 a pak Panel2) - snad je to to, na co ses ptal :)

 
Nahoru Odpovědět
12.6.2013 17:49
Avatar
tomas
Člen
Avatar
Odpovídá na Jan Vargovský
tomas:12.6.2013 20:37

ne mam to jen v jednom, v tom druhem je jen datagrid

 
Nahoru Odpovědět
12.6.2013 20:37
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na tomas
Jan Vargovský:12.6.2013 22:50

No, toje fuk... A je to to, co jsi myslel?

 
Nahoru Odpovědět
12.6.2013 22:50
Avatar
tomas
Člen
Avatar
Odpovídá na Jan Vargovský
tomas:12.6.2013 23:13

jo je to ono, kousek víš už jsem to podobně vyřešil. diky

 
Nahoru Odpovědět
12.6.2013 23:13
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 29 zpráv z 29.