Diskuze: Hromadná změna pozadí u více labelů

C# .NET .NET (C# a Visual Basic) Hromadná změna pozadí u více labelů American English version English version

Avatar
Peca
Člen
Avatar
Peca:

Zdravím, mám aplikaci, kde je picture box a na něm je několik labelů. Chci, aby se všem labelům změnilo pozadí na průhledné. Ted mi to funguje tak, že se pozadí změní vždy jen u poloviny labelů a u druhé poloviny se nezmění, at jsou labely 2, nebo jich je 20, pokaždé to funguje jenom u poloviny. Zkoušel jsem to napsat různými způsoby a nepovedlo se mi to rozchodit podle mých představ. V čem mám chybu?

Ani na takovéhle jednoduché aplikaci, kde skoro nic není mi to nefunguje:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            foreach (Control ctrl in this.Controls.OfType<Label>())
            {
                {
                    ctrl.Parent = pictureBox1;
                    ctrl.BackColor = Color.Transparent;
                }
            }
        }
    }
Editováno 16.2.2014 0:02
 
Odpovědět 16.2.2014 0:02
Avatar
Peca
Člen
Avatar
Peca:

Zjistil jsem, že když ten cyklus foreach dám na tlačítko místo na událost load a pak když na to tlačítko několikrát kliknu, tak po každém kliknutí se zprůhlední pozadí u poloviny labelů z celkového počtu, kde pozadí průhledné není. Takže když mám 16 labelů, tak po prvním kliknutí se jich zprůhlední 8, po druhém kliknutí zbydou neprůhledné 4, po dalším kliknutí se zprůhlední další 2, po dalším kliknutí zbyde už jen jeden a nakonec je průhledné pozadí u všech labelů. :D Proč se tohle děje?

Editováno 16.2.2014 0:11
 
Nahoru Odpovědět 16.2.2014 0:10
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na Peca
Petr Nymsa:

Teď mě akorát napadá

foreach(Label lbl in this.Controls)
  lbl.BackColor = Color.Transparent;
Nahoru Odpovědět 16.2.2014 0:19
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
rwn
Člen
Avatar
rwn:

Můžeš zkusit ten cyklus dát do události pictureBox1_Paint, ale pak se ti budou labely pozicovat vzhledem k pictureBoxu a ne Formu.

Nahoru Odpovědět 16.2.2014 1:52
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
rwn
Člen
Avatar
rwn:

A jinak se to asi děje tím cyklem, když jsem si to zkusil s 5 Labely krokovat, tak se ten cyklus provedl jen 3krát; (Hrozně mě to připomíná situaci, když se maže z Listu od první položky, pak se posouvá pořadí položek a když to není ošetřeno, tak to přeskakuje podobně).

Nahoru Odpovědět 16.2.2014 2:16
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
Peca
Člen
Avatar
Peca:

Zirko:
To mi nějak nefunguje vůbec.

rwn:
Dal jsem to do událoti pictureBox_Paint a ono to funguje. Jiné pozicování mi nevadí. Neni to ale moc dobré řešení, protože zrovna tuhle událost vyvolávám celkem často (každých 25ms) na základě časovače, protože tam mám už jiný kod (Graphics.Dra­wImage). Prostě to ten cyklus ve výsledku zpomaluje. Tak mě napadlo dát to do podmínky dotazované na pomocnou proměnnou a po projetí cyklu změnit stav pomocné proměnné, takže díky tomu cyklus projede jen jednou. A jsem tam, kde jsem byl. Když nechám cyklus projet vícekrát, tak to má stejný efekt, jako jsem výše popisoval to klikání na tlačítko. Takže když ten cyklus foreach nechám projet asi 4x tak je výsledek dobrý, ale i tak mi to trošku zpomaluje tu aplikaci.

Zatím jsem to vyřešil tak, že ten původní cyklus foreach (ten, co je v mém prvním příspěvku) jsem dal do cyklu for, který proběhne 4x a to celé je dané v události Form1_load. Takže takhle mi to funguje, ale nevím, jak si to odůvodnit. Nevím proč to pokaždé změní požadované vlastnosti jen u poloviny prvků (kontrolek).

Editováno 16.2.2014 11:17
 
Nahoru Odpovědět 16.2.2014 11:15
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Peca
Jan Vargovský:

Můžeš někde upnout ten projekt? Nechce se mi to simulovat tak nato kouknu přímo.

 
Nahoru Odpovědět 16.2.2014 13:41
Avatar
Peca
Člen
Avatar
Peca:

http://uloz.to/…i-labelu-rar

V poznámce tam je ten cyklus for, se kterým mi to funguje. Není to ale nejlepší řešení, i když pro tuto aplikaci asi dostačující. Hlavně by mě zajímal důvod, proč ten cyklus foreach provede požadovanou operaci vždy jen pro polovinu kontrolek. :)

 
Nahoru Odpovědět 16.2.2014 14:16
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Peca
Jan Vargovský:
foreach (Control ctrl in this.Controls.Cast<Control>().ToList())
{
...
}
 
Nahoru Odpovědět 16.2.2014 14:48
Avatar
Peca
Člen
Avatar
Peca:

Díky moc. Už to funguje. To by mě zajímalo, proč to musí být zrovna takhle. :)

 
Nahoru Odpovědět 16.2.2014 14:55
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Peca
Jan Vargovský:

Jde o to, že když nastavíš Parent každému controlu, tak zmizne z té kolekce, takže pokaždé když nastavíš Parent tomu kontrolu, tak máš počet - 1, pak to zblbne ten enumerátor a proiteruje jen část. Takže si je takhle uložíš napevno do kolekce a iteruješ jí a je jedno k jaké kontrolce patří.

Jinak všechno tohle bys nemusel řešit, kdybys použil panel, který je přesně na tyhle věci (skládání kontrolek do nečeho). Ty třeba ještě nemusíš řešit to, že to máš přes celý form, ale jakmile bys měl ten picturebox třeba jen poloviční, musel bys přepočítávat lokaci apod. takže to změn na Panel a budeš to mít lehčí.

 
Nahoru Odpovědět 16.2.2014 15:20
Avatar
Peca
Člen
Avatar
Peca:

OK. Díky moc za vysvětlení. Už je mi to jasné.

 
Nahoru Odpovědět 16.2.2014 15:33
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 12 zpráv z 12.