Diskuze: Odkaz na dynamicky vytvorene kontrolky

C# .NET .NET (C# a Visual Basic) Odkaz na dynamicky vytvorene kontrolky American English version English version

Avatar
Rahti
Člen
Avatar
Rahti:

Zdravicko,

resim takovy problem. Budu mit grid (rekneme 13x13), a rad bych (z ohledem treba na vysledek dotazu) vkladal kontrolky (pro jednoduchost textboxy), ktere bych si pojmenovaval, daval jim pozici v gridu a treba columnspan atribut. Nevim, zda jsem vybral optimalni postup, ale jiny mne nenapada.

S tim, ze kod co me napadl zatim :

public MainWindow()
  {
      InitializeComponent();
      pridejControlku(3, 3, "okraj1");
  }

  private void Button_Click(object sender, RoutedEventArgs e)
  {
      //zde bych rad pracoval s kontrolkou okraj1

  }

  private void pridejControlku(int p1, int p2, string jmeno)
  {
      Border okraj = new Border();
      okraj.BorderThickness = new Thickness(3);
      okraj.BorderBrush = Brushes.Aqua;
      okraj.Width = 50;
      okraj.Height = 50;
      Grid.SetRow(okraj, p1);
      Grid.SetColumn(okraj, p2);
      grid.Children.Add(okraj);
      okraj.Name = jmeno;
  }
 
Odpovědět 2.10.2015 7:30
Avatar
Jan Demel
Redaktor
Avatar
Odpovídá na Rahti
Jan Demel:

Ahoj :) Pokud jsem správně pochopil, jde ti hlavně o to, aby jsi s objektem okraj mohl pracovat v metodě Button_Click. Toho docílíš opravdu jednoduše a to tak, že objekt okraj vytvoříš jako privátní proměnnou třídy a to asi takhle.

private Border okraj; // Tady si vytvořít proměnnou
public MainWindow()
{
    InitializeComponent();
    pridejControlku(3, 3, "okraj1");
    okraj = new Border(); // A tady jí předáš objekt třídy Border
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    //zde bych rad pracoval s kontrolkou okraj1

}

private void pridejControlku(int p1, int p2, string jmeno)
{
    // Zde už pracuješ s privátní proměnnou třídy
    okraj.BorderThickness = new Thickness(3);
    okraj.BorderBrush = Brushes.Aqua;
    okraj.Width = 50;
    okraj.Height = 50;
    Grid.SetRow(okraj, p1);
    Grid.SetColumn(okraj, p2);
    grid.Children.Add(okraj);
    okraj.Name = jmeno;
}
Nahoru Odpovědět 2.10.2015 8:12
To co se zdá být nemožné, je vždy možné.
Avatar
Jan Demel
Redaktor
Avatar
Odpovídá na Rahti
Jan Demel:

Zapomněl jsem do toho kódu dodat. V té metodě Button_Click s okrajem budeš pracovat stejně jako v metodě pridejControlku :)

Nahoru Odpovědět 2.10.2015 8:13
To co se zdá být nemožné, je vždy možné.
Avatar
Rahti
Člen
Avatar
Rahti:

Spatne jsem to napsal :( Jde mi o to, ze tech okraju vytvorim treba 10 a potom budu pracovat prave s nejakym konkretnim v metode Button_click. S tim, ze pocet vytvorenych okraju bude podle vysledku z databaze(muze byt treba libovolne cislo od 1-10).

 
Nahoru Odpovědět 2.10.2015 8:36
Avatar
Jan Demel
Redaktor
Avatar
Odpovídá na Rahti
Jan Demel:

Ok. Teďka budu vařit trošku z vody. Ale dalo by se to udělat tak, že si vytvoříš privátní proměnnou okraje datového typu List<Border> (teď si nejsem úplně jistý, jestli to jde - asi rok jsem v tom nedělal) a v metodě pridejKontrolku budeš pracovat už s tím listem.

Nahoru Odpovědět 2.10.2015 8:42
To co se zdá být nemožné, je vždy možné.
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Rahti
Jan Vargovský:

Pretypuj si parametr sender.

 
Nahoru Odpovědět 2.10.2015 8:50
Avatar
ostrozan
Redaktor
Avatar
ostrozan:

Máš v tom trochu hokej :-)
vím, že je to jen příklad, ale chceš přidávat TexBox, metodu máš pro přidání Border a zpracovat to chceš v Button_click ?

Pokud ti jde o to jak zpracovat události z více kontrolek v jediné metodě - tak zde je v rozvinuté podobě rada Jana:

private void Border_click(object sender, MouseEventArgs e)
       {
           //pretypujes si object sender na Border
           Border border = sender as Border;

           //pak si muzes delat co chces
           border.Background=Colors.Green;//zmeni ti barvu pozadi prave toho borderu, na ktery jsi klikl
       }

s Borderem stejně nemůžeš dělat nic jiného, než mu měnit vlastnosti

pokud bys ale chtěl pracovat s TextBoxy a jejich texty ukládat do různých proměnných tak už bys musel identifikovat, která kontrolka událost vyvolala a kam výsledek poslat - což je jednoduché při pevně daném počtu kontrolek ale v tvém případě je to složitější a měl bys proto být konkrétnější.

Editováno 2.10.2015 10:04
 
Nahoru Odpovědět 2.10.2015 10:03
Avatar
Rahti
Člen
Avatar
Rahti:

Jak jsem uz psal jednou, napsal jsem to spatne.
Tj. jeste jednou priklad je Border, ale obecne bych to rad vyresil pro jakoukoliv kontrolku (ve finale budu pouzivat nejakou svou kontrolku).

S tim, ze tohle je snad ted prehlednejsi kod :

    int pocetRadku = 0;

    public MainWindow()
    {
        InitializeComponent();
        pocetRadku = zjistiPocetRadku();
        if (pocetRadku > 0)
        {
            for (int j = 0; j < pocetRadku; j++ )
            {
                for (int k = 0; j < grid.ColumnDefinitions.Count; k++)
                    pridejControlku(j, k, "okraj" + j.ToString() + k.ToString());
            }
        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        //zde bych rad pracoval s konkretnim borderem, napr. okraj23


    }

    private void pridejControlku(int p1, int p2, string jmeno)
    {
        Border okraj = new Border();
        okraj.BorderThickness = new Thickness(3);
        okraj.BorderBrush = Brushes.Aqua;
        okraj.Width = 50;
        okraj.Height = 50;
        Grid.SetRow(okraj, p1);
        Grid.SetColumn(okraj, p2);
        grid.Children.Add(okraj);
        okraj.Name = jmeno;
    }
}

Ale jak ted nejak zkousim (jak me navedl Jan Demel) a premyslim, tak bych po vytvoreni kontrolky ji hodil do Dictionary<strin­g,Border> a pak se na to nejak odkazoval.

 
Nahoru Odpovědět 2.10.2015 10:35
Avatar
ostrozan
Redaktor
Avatar
Odpovídá na Rahti
ostrozan:

Kdysi jsem něco v tomto duchu zkoušel, tak jsem to "vyhrabal" - snad ti to pomůže

je to prográmek, který za běhu přidává kontrolky TextBox a TextBlock po kliknutí na Button text psaný do TextBoxu se kopíruje do příslušného TextBlocku

pro přidávání kontrolek za běhu je asi šikovnější StackPanel - tam prostě jenom jednoduše metodou StackPanel.Chil­dren.Add(kontrol­ka) přidáš co chceš a nemusíš se starat o nějakou pozici - StackPanel si je přidává automaticky za, nebo pod sebe (podle orientace) určuješ pouze pozici první kontrolky a to pozicí StackPanelu

shodou okloností jsem taky použil Dictionary

pro úplnost a kdyby to někdo chtěl zkusit tady je XAML

<Grid>
       <Grid.RowDefinitions>
           <RowDefinition Height="51*" />
           <RowDefinition Height="260*" />
       </Grid.RowDefinitions>
       <Grid.ColumnDefinitions>
           <ColumnDefinition Width="496*" />
           <ColumnDefinition Width="7*" />
       </Grid.ColumnDefinitions>
       <Button Height="20" Width="60" Margin="0" Click="Button_Click" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="0">pridej</Button>
       <StackPanel Orientation="Horizontal" Name="stackHlavni" Width="auto" Margin="0,5,0,0" Grid.ColumnSpan="2" Grid.Row="1">
           <StackPanel Name="stack1" HorizontalAlignment="Center" VerticalAlignment="Top"></StackPanel>
           <StackPanel Name="stack2" HorizontalAlignment="Center" VerticalAlignment="Top" ></StackPanel>
       </StackPanel>
   </Grid>

a tady kód

public partial class MainWindow:Window
  {
      public MainWindow()
      {
          InitializeComponent ();
      }


      private Dictionary<TextBox,TextBlock> Parovani_kontrolek=new Dictionary<TextBox,TextBlock> ();


      private void Button_Click(object sender,RoutedEventArgs e)
      {
          Pridej_kontrolky ();
      }


      private void Pridej_kontrolky()
      {
          TextBox tbx=new TextBox ();
          TextBlock tbl=new TextBlock ();

          //property TextBoxu
          tbx.Height=20;
          tbx.Width=50;
          tbx.Margin=new Thickness (10);
          tbx.HorizontalAlignment=HorizontalAlignment.Center;
          tbx.BorderBrush=Brushes.Black;
          tbx.Background=Brushes.Beige;

          // handler pro TextChanged
          tbx.TextChanged+=new TextChangedEventHandler (tb_TextChanged);
          //pridani kontrolky
          stack1.Children.Add (tbx);

          //property TextBlocku
          tbl.Height=20;
          tbl.Width=50;
          tbl.Margin=new Thickness (10);
          tbl.HorizontalAlignment=HorizontalAlignment.Center;
          tbl.Background=Brushes.Beige;

          //pridani kontrolky
          stack2.Children.Add (tbl);

          //pridani polozky do slovniku key=TextBox value=TextBlock
          Parovani_kontrolek.Add (tbx,tbl);

      }


      private void tb_TextChanged(object sender,RoutedEventArgs e)
      {
          //pretypovani na TextBox
          TextBox tbx=sender as TextBox;

          //prirazeni prislusneho TextBlocku
          TextBlock tbl=Parovani_kontrolek[tbx];

          //akce
          tbl.Text=tbx.Text;
      }
  }

místo TextBoxu a TextBlocku si dosaď svoje objekty - Dictionary pak můžeš třeba XML serializerem uložit do souboru a pak při spuštění aplikace načíst a vytvořit kontrolky podle něj

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět 3.10.2015 13:44
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 9 zpráv z 9.