Prevest objekt na form ci control a ziskat z nej controly   otázka

C#, WinForms

Dobrý den

Udělal jsem si proceduru, kam do argumentu dám promennou typu Form.

Účel procedury:

Zavolám ji a do argumentu dám volající form. Pak projíždím všechny kontroly (Controls) a upravuji jejich nastavení (přidávám handlery, obrázky atd.), a tím mi to pro aplikaci vytvoří příjemné GUI (obrázky se mění, když myš najede na button atd.)

public void do_graphics(Form f)
{
 foreach (Control cont in f.Controls)
                {
              if(cont is ListView)
                    {
                    }
             //atd atd
                }
}

Problém:

Když narazím na Panel (ci jiný control, který může mít v sobě další controly), chci i pro ně získat stejné nastavení.

Nejdříve mne napadla rekurze, ale protože jsem do procedury dával promennou typu Form, nemůžu dát do argumentu Control.

Nakonec jsem proceduru přetížil (jedna s argumentem pro form a druhá pro Control), ale protože jedna procedura má asi 100 + řádků, a i pro to, že kdybych v jedné něco změnil, musel bych to změnit i v té druhé, jsem toto řešení také zavrhl

Napadlo mne dát do argumentu Objekt. Ale ve foreach mne to psalo chybu, protože u objektu nemůže zjistit controls, I když jsem to převedl na form nebo Control. Zkoušel jsem i var.

public void do_graphics(Object o)
{

foreach (Control cont in ((o.GetType())o).Controls)
                {
                }
}

Nevíte někdo nějaký inteligentní řešení? Děkuju za případné odpovědi.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Form dědí z Control, použijte pouze variantu, která bere jako parametr Control a rekurzivně jí volejte pro ovládací prvky, které chcete.

Rodokmen třídy form je patrný na MSDN:

http://msdn.microsoft.com/en-us/library/...

Implementace by tedy mohla vypadat následovně:

(Uvádím zdroj ve VB .NET, vzhledem k tomu, že jsme na webu o VB .NET, ale není to těžké přepsat/převést do C#)

  Private Sub SetTextBoxes(control As Control)
    For Each childControl As Control In control.Controls
      If TypeOf childControl Is TextBox Then
        DirectCast(childControl, TextBox).Text = "This TextBox.Text was set by SetTextBoxes method."
      ElseIf TypeOf childControl Is Label Then
        DirectCast(childControl, Label).Text = "This Label.Text was set by SetTextBoxes method."
      ElseIf TypeOf childControl Is CheckBox Then
        Dim checkBox = DirectCast(childControl, CheckBox)
        checkBox.Text = "This CheckBox.Text was set by SetTextBoxes method."
        checkBox.Checked = True
      ElseIf childControl.Controls.Count > 0 Then
        SetTextBoxes(childControl)
      End If
    Next
  End Sub

Poznámka: Každý Control může mít své potomky, ne pouze Panel, TabControl a podobně, protože vlastnost Controls je definovaná už na třídě Control, jak je též patrné z MSDN. V mém příkladu jsem tedy použil If-ElseIf-End If konstrukci, kde vybírám typy, které se mi líbí a pokud žádný nenaleznu, rovnou rekurzivně předám dále. Tady možná budete chtít přepsat z "Else" na další ElseIf podmínku a přidat tam jen Panel, GroupBox a podobně, protože jinak Vám to bude volat i věci jako NumericUpDown (který má v sobě tlačítka) atp.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Pokud jsem to dobře pochopil, tak pak mám tuto proceduru volat nějak takto?

Private void Form1_load(object sender, eventargs e)
{
foreach(control c in this.controls)
   {
    setTextBoxes(c);
   }
}

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nikoliv. Stačí zavolat:

Private void Form1_load(object sender, eventargs e)
{
  setTextBoxes(this);
  // Případně setTextBoxes((Control)this); pokud se to nebude kompilátoru líbit, nemám to teď jak vyzkoušet
}

Protože setTextBoxes přijme jako parametr jak Form, tak Control (Form dědí z Control), takže ten foreach cyklus tam už se vyřeší v rámci setTextBoxes. Když to zavoláte s Formem (this), tak:

private void setTextBoxes(Control c)
{
  foreach(Control childControl in c.Controls) // Tady se volá ten cyklus, který jste Vy použil v handleru Form1_Load, je stejný jak pro parametr typu Form, tak Control
// ...
nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Mockrát děkuju

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback