Dynamiczne tworzenie kontrolek i odczytywanie z nich danych

0

Witam,
Szukam pomocy a może przykładu kodu, który realizuje np: dynamiczne tworzenie kontrolek (np textbox) a potem sczytuje z nich wielkości. Może to być też program (część), która służy do rysowania kontrolek dynamicznie a potem ich usuwania z formy. Mam problem z adresowaniem...jak adresowac konkretną kontrolkę w pętli?? Znalazłem kilka przykładów, gdzie kontrolki są tworzone dynamicznie ale brakuje mi tam jakiegoś nueru, wskaźnika który odpowiadałby akurat tej danej kontrolce. Tak żeby potem w innej pętli sczytać wartości z kontrolki czy tez zmienić jej właściwość
Pozdrawiam
Z góry dziękuję za wszelką pomoc...

0

Najprościej będzie umieścić te kontrolki w tablicy.

0

Zrobiłem coś takiego ale nie chce mi to działać wywala błąd w ustawieniach położenia...Chyba nie mogę tak tworzyć. Nikt mi tego nie potrafi wytłumaczyć a borykam się z tym jak i reszta znajomych z klasy. Tworzyć dynamicznie elementy umiem ale nie potrafię ich stworzyć w pętli tak żeby je narysować, potem wpisać do nich dane no i potem te dane sczytać do dalszej obróbki programowej

  private void button1_Click(object sender, EventArgs e)
        {
          Tablica = new double [5]; 

            for(int i =0; i<5;i++)
            {
                TextBox [] textowo = new TextBox[5];
                textowo[i].Top = 10+(i*5);
                textowo[i].Name = "TextBoxes" + i.ToString();
                this.Controls.Add(textowo[i]);
            }
        }
0

Nie działa, bo nie tworzysz w ogóle ani jednego obiektu typu TextBox. Tworzenie tablicy nie powoduje utworzenia w niej elementów!
A poza tym tworzysz tablicę jako lokalną zmienną pętli - jak chcesz się do niej gdzieś odwołać, skoro ta tablica jest na nowo tworzona w każdym przebiegu pętli? Powinna być polem klasy.

0

Po co ci w ogóle ta tablica?. w pętli tworzysz swoje obiekty (np TextBox twojaKontrolka = new TextBox()), nadajesz im jakie tam chcesz właściwości i dodajesz do kolekcji tak jak to zrobiłeś poprzez this.Controls.Add(twojaKontrolka). W czym masz problem...

0

Żeby potem się odwołać do danej kontrolki. Jak w pętli sprawdzać nazwę?? Tworzenie dynamiczne to nie problem tylko potem jak w pętli odwołać się do konkretnego textboxu i sczytać z niego zawartość

0

Odwołujesz się wtedy do kolekcji kontrolek:

this.Controls[indexKontrolki] lub this.Controls[nazwaKontrolki]

czyli np:

TextBox kontrolka =  (TextBox)this.Controls[nazwaKontrolki]
0

No właśnie z nazwami może być problem. Ręcznie stworzyłem 36 textbox o nazwach a11,a12,a13,a14,a15,a16 a potem a21, a22 itd. Teraz siedzę i męczę się z opanowaniem tego (pętle). Po nazwie to chyba nie dam rady. Wolałbym po indeksie. A czy indeks to jest .Tag?

0

Po nazwach wnioskuję, że chcesz jakąś macierz zbudować z tych TextBoxów, więc dlaczego po prostu nie użyjesz do tego dwuwymiarowej tablicy? W każdej komórce przechowasz sobie kontrolkę i po kłopocie.

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

        private void button1_Click(object sender, EventArgs e)
        {

            for(int cnt=0;cnt<=5;cnt++)
            {
                TextBox textbox = new TextBox();
                textbox.Name = "textboxi" + cnt.ToString();
                textbox.Location = new System.Drawing.Point(30,30*cnt);
                textbox.Size = new System.Drawing.Size(90, 20);
                textbox.TabIndex = cnt;
                textbox.Visible = true;
                this.Controls.Add(textbox);
            }
        }
    }

A czy przykładowo da się w trakcie tworzenia tych tekstboxów dodać jakiś znacznik??Jakieś ID czy coś tego typu??

Do tego przykładu treningowego dodam np tablicę:

 double [] tablica = new double [6]

I potem np zrobię pętlę

 for (int i =0; i<=5;i++)
{
tablica [i] = textbox ......

w miejscu ..... pasowało umieścić to ID czy coś w tym stylu... o takie coś mi chodzi...A zbawienie mnie obejmie...po kilku dniach szukania wyjścia;/

Ewentualnie czy możecie mi powiedzieć jak się potem odwołać do komórek??

 namespace WindowsFormsApplication7
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        TextBox[] textboxy;
        private void button1_Click(object sender, EventArgs e)
        {
            textboxy = new TextBox[5];
            int cnt=0;
            int topPosition = 10;
            foreach (TextBox wyniki in textboxy)
            {
                TextBox textbox = new TextBox();
                textbox.Left = 10;
                textbox.Top = topPosition;
                topPosition += 30;
                textbox.Text = "textboxy" + " " + cnt.ToString();
                this.Controls.Add(textbox);
                cnt++;
            }
        }

        private void Wczytaj_Click(object sender, EventArgs e)
        {
            double [] tablica = new double[5];
            for (int i=0;i<=4;i++)
            {
               
               tablica[i] = .....
            }
        }


    }
}

Chodzi o miejsce tablica[i]...dawałem tam = double.Parse(textboxy[i].ToString());
Ale mam błąd niewłaściwy format wejściowy...
Jak dam = double.Parse(textboxy[i].Text.ToString());
To mam błąd Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu

Odwołujesz się wtedy do kolekcji kontrolek:

this.Controls[indexKontrolki] lub this.Controls[nazwaKontrolki]

czyli np:

TextBox kontrolka = (TextBox)this.Controls[nazwaKontrolki]

Robiłem tak jak piszesz. Jeśli ręcznie wpiszę nazwę kontrolki to wszystko działa. Ale w momencie gdy zrobię pętlę, a w niej tablicę, do której będę zapisywać wartości z textboxów filtrowanych po nazwach, pojawia się błąd:
Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu

1

Ale ty w ogóle nie wypełniłeś tej tablic textboxy. Utwórz kontrolki tak:

namespace WindowsFormsApplication7
{
    public partial class Form1 : Form
    {
        private TextBox[] textboxy;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            textboxy = new TextBox[5];
            for (int i = 0; i < textboxy.Length; i++)
            {
                textbox[i] = new TextBox();
                textbox[i].Left = 10;
                textbox[i].Top = i * 30 + 10;
                textbox[i].Text = "textboxy " + i.ToString();
                this.Controls.Add(textbox[i]);
            }
        }
    }
}

Później możesz się odwołać do i-tego textbox'a przez:

textboxy[i]

np. aby zamienić zawartość i-tego texbox'a na liczbę typu double zrób

double wartosc;
if (Double.TryParse(textboxy[i].Text, out wartosc))
{
    MessageBox.Show(String.Format("Wartość wpisana do textbox'a nr. {0}: {1}", i, wartosc));
}
else
{
    MessageBox.Show(String.Format("Zawartość textbox'a nr. {0} nie jest liczbą", i));
}
0

Dzięki wielkie za pomoc o to chodziło (część pierwsza). Druga działa ale chciałbym to zapisać do tablicy a nie tak jak Ty napisałeś (w Messagebox).
Zamiast drugiej części napisałem coś takiego...bo o to mi chodzi ale wywala mi błąd przy wpisywaniu do tablicy

        private void button2_Click(object sender, EventArgs e)
        {
            double[] tablica = new double[5];
            for (int i = 0; i < 5; i++)
            {
                tablica[i] = double.Parse(textboxy[i].Text.ToString());
            }
        } 

Nieprawidłowy ciąg wejściowy...
Da się to jakoś ominąć? Inaczej to zapisać czy coś?

Ok działa
tablica[i] = double.Parse(textboxy[i].Text);

0

Mam małe pytanie jeszcze. Posiadam dwie klasy...w pierwszej z nich posiadam zmienną n, która czytam z textboxa. program się wykonuje, przechodzi przez delegacje do drugiej klasy, tam dokonywane są obliczenia i wraca do klasy podstawowej....problem pojawia się w miejscu powrotu bo nagle zmienna n mimo modyfikatoru dostępu private się zeruje...Czemu się tak dzieje?

Czemu nie mogę dodać DataGridView?

    public void RysowanieMacierzy(double[,] B)
    {
        // n czytane raz jeszcze ponieważ gdzieś się zerowało, nie udało się znaleść miejsca zerowania...
        n = B.GetLength(0);
        double[,] tablicazmienna = new double[n, n + 1];

        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n + 1; j++)

                tablicazmienna[i, j] = B[i, j];
        }
        DataGridView data = new DataGridView();
        this.tabPage2.Controls.Add(data);
    }

Dodam że jak stworze obiekt klasy datagridview pod przyciskiem, to wtedy się rysuje normalnie a jak wpiszę do tej funkcji to nic się nie pojawia na tabPage2... co jest nie tak?

0
ravers_19 napisał(a):

Mam małe pytanie jeszcze. Posiadam dwie klasy...w pierwszej z nich posiadam zmienną n, która czytam z textboxa. program się wykonuje, przechodzi przez delegacje do drugiej klasy, tam dokonywane są obliczenia i wraca do klasy podstawowej....problem pojawia się w miejscu powrotu bo nagle zmienna n mimo modyfikatoru dostępu private się zeruje...Czemu się tak dzieje?

Pokaż kod.

0

Hmm może to pominę a zapytam coś bardziej konkretnego

        private void RozwiazUkladRownan_Click(object sender, EventArgs e)
        {
            tablica = new double [n, n + 1];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j <= n; j++)
                {
                    tablica[i, j] = double.Parse((textboxy[i, j].Text));
                }
            }    

           WspolczynnikiA = new double[1 + 1];
           WspolczynnikiA = RownaniaLinioweTrojkatna_Gauss.MetGauss(tablica);
           WynikiObliczen(tablica);
        }


        public void WynikiObliczen(double [,] B)
        {
            DataGridView przyci = new DataGridView();
            this.tabPage2.Controls.Add(przyci);
        }

Teraz pytanie...
Czemu jak wywołuję metodę WynikiObliczeń z pozycji funkcji RozwiazUkladRownan_Click to rysowany jest DataGridView a jak wywołam metodę Wyniki obliczeń poprzez

RownaniaLinioweTrojkatna_Gauss.MetGauss(tablica)

To DatagridView już nie jest rysowany. Wszystko działa cacy bez błędów a mimo to grid nie jest rysowany. Dodam, że RownaniaLinioweTrojkatna_Gauss.MetGauss to inna klasa. Macierz z tej klasy wysyłam poprzez

RownaniaLinioweGauss macierzPrzejsciowa = new RownaniaLinioweGauss();
macierzPrzejsciowa.WynikiObliczen(C)

Gdzie C to macierz [,]

    class Rownania
    {
        public static double[] Met(double[,] A)
        {
            int i, j, s, N;
            double sumac;
            double[,] C;
            double[] x;
                      
            N = A.GetLength(0);
            C = new double[N, N + 1];
            x = new double[N];

            for (i = 0; i < N; i++)
            {
                for (j = 0; j < N + 1; j++)

                    C[i, j] = A[i, j];
            }

            for (s = 0; s < N - 1; s++)
            {
                for (i = s + 1; i < N; i++)
                {
                    for (j = s + 1; j < N + 1; j++)

                        C[i, j] = C[i, j] - (C[i, s] / C[s, s]) * C[s, j];   
                }
                         xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
            }
        }
    } 

W miejscu gdzie są xxxxxxxxxxxxxxxxxxxxxxxxxxx, chciałbym przesyłać macierz do klasy podstawowej. Nie wiem jak to zrobić...Tworzyłem tutaj obiekt typu Klasa podstawowa i wywoływałem metodę z klasy podstawowej. Działało....dane się zapisywały lecz potem miałem problem z odwołaniem się do nich w klasie pierwszej...może ktoś podsunie mi pomysł jakiś...

1 użytkowników online, w tym zalogowanych: 0, gości: 1