Zdarzenie dla dynamicznie dodanego formularza.

0

Siema.

Mam pewien problem, potrzebuje po wciśnięciu buttona stworzyć dynamicznie nową formę zawierającą kilka labeli, textboxów i ze dwa buttony. Stworzenie formy to nie problem, kod wygląda tak:

 public void parametrysieci_Click(object sender, EventArgs e)
        {
            
            Form dlg = new Form();
            dlg.Size = new System.Drawing.Size(500, 500);
            dlg.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            dlg.ShowDialog();
            //dlg.Load += new System.EventHandler(dlg_Load);
        }

I wszystko działa pięknie, tworzy mi nową formę. Jednak muszę do niej dynamicznie dodać jeszcze kilka rzeczy i tutaj stanąłem. Np.

 Label tekst = new System.Windows.Forms.Label();
            tekst.Location = new System.Drawing.Point(200, 200);
            tekst.AutoSize = true;
            tekst.Name = "label2";
            //tekst.TabIndex = 10;
            tekst.Size = new System.Drawing.Size(30, 30);
            tekst.Text = "Napięcie znamionowe";
            //Point polozenie = new Point(100, 100);
            //tekst.Location = polozenie;
            tekst.ForeColor = System.Drawing.Color.Black;
            tekst.Visible = true;
            tekst.Enabled = true;
            this.Controls.Add(tekst);

Podejrzewam, że najłatwiej byłoby dodać te wszystkie potrzebne im kontrolki w nowym zdarzeniu dla tej formy, np dlg_Load, czyli gdy ta forma się załaduje, mają tam powstać dane kontrolki. Jednak nie mam bladego pojęcia jak dodać zdarzenie dla dynamicznie dodanego formularza..

Jest w stanie mi ktoś pomóc?

Pozdrawiam, Mateusz

0

czemu w ogóle chcesz ją tworzyć w ten sposób, kodem? Czemu nie stworzysz osobnej klasy dla tej formy dziedziczącej po Form?
I po co chcesz żeby kontrolki dodawały się w dlg_Load? Możesz je dodać od razu po stworzeniu formy:

            Form dlg = new Form();
            dlg.Size = new System.Drawing.Size(500, 500);
            dlg.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;

            Label tekst = new System.Windows.Forms.Label();
            tekst.Location = new System.Drawing.Point(200, 200);
            tekst.AutoSize = true;
            tekst.Name = "label2";
            //tekst.TabIndex = 10;
            tekst.Size = new System.Drawing.Size(30, 30);
            tekst.Text = "Napięcie znamionowe";
            //Point polozenie = new Point(100, 100);
            //tekst.Location = polozenie;
            tekst.ForeColor = System.Drawing.Color.Black;
            tekst.Visible = true;
            tekst.Enabled = true;
            dlg.Controls.Add(tekst);

            dlg.ShowDialog();

ale jeśli bardzo chcesz w zdarzeniu Load:

            Form dlg = new Form();
            dlg.Size = new System.Drawing.Size(500, 500);
            dlg.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;

            dlg.Load += (dlg_o, dlg_e) =>
            {
                var that = dlg_o as Form; // zboczenie z javascript?
                Label tekst = new System.Windows.Forms.Label();
                tekst.Location = new System.Drawing.Point(200, 200);
                tekst.AutoSize = true;
                tekst.Name = "label2";
                //tekst.TabIndex = 10;
                tekst.Size = new System.Drawing.Size(30, 30);
                tekst.Text = "Napięcie znamionowe";
                //Point polozenie = new Point(100, 100);
                //tekst.Location = polozenie;
                tekst.ForeColor = System.Drawing.Color.Black;
                tekst.Visible = true;
                tekst.Enabled = true;
                that.Controls.Add(tekst);
            }; // tę funkcję możesz wydzielić

            dlg.ShowDialog();
1

potrzebuje po wciśnięciu buttona stworzyć dynamicznie nową formę zawierającą kilka labeli, textboxów i ze dwa buttony

Czy to jest treść zadania?
Bo nie widzę powodu by tak kombinować. Po prostu stwórz w designerze nową formę i otwieraj ją na żądanie...

var form2 = new Form2();
// size, position, co tam trzeba…
form2.ShowDialog(this);

formalnie jest to i tak „dynamicznie”, bo kontrolki są tworzone przez konstruktor Form2()

0

Właśnie kurde chciałem tak zrobić w pierwszej wersji. Całą formę sobie przygotować w designerze i po prostu sobie ją wywoływać kiedy mi potrzebna. Nie wiem dlaczego ale jak pokazałem to mojemu prawdopodobnie recenzentowi, który jest w tym biegły to powiedział, żebym tak nie robił tylko wszystko za pomocą okien dialogowych rozwiązał ;o

I nie działa w żaden ze sposobów przedstawionych powyżej niestety. Po prostu ten label nie pojawia się w nowo otwartej formie, tylko w tej "starej".

0

Generalnie rzecz biorąc, piszę pracę magisterską i potrzebuje napisać program wspomagający projektowanie sieci średniego napięcia. Po kliknięciu w button, powinna otwierać się nowa forma z textboxami, w których wprowadzam pewne dane (napięcie, współczynniki itp. itd.). Chodzi o to, aby dane wprowadzone w tym "nowym" formularzu były dostępne dla formularza "bazowego" gdyż tam będą obliczenia.

1
maciaba napisał(a):

Właśnie kurde chciałem tak zrobić w pierwszej wersji. Całą formę sobie przygotować w designerze i po prostu sobie ją wywoływać kiedy mi potrzebna. Nie wiem dlaczego ale jak pokazałem to mojemu prawdopodobnie recenzentowi, który jest w tym biegły to powiedział, żebym tak nie robił tylko wszystko za pomocą okien dialogowych rozwiązał ;o

przecież to dalej jest to samo okienko - nie wiem jak wyglądał Twój program ale zapewne źle go zrozumiałeś i chodzi o coś innego - być może o to żeby ustawić typ obramowania na dialogowe (bez przycisków maksymalizacji, itp), albo o to że użyłeś Form.Show zamiast Form.ShowDialog nie robiąc okienka modalnym

I nie działa w żaden ze sposobów przedstawionych powyżej niestety. Po prostu ten label nie pojawia się w nowo otwartej formie, tylko w tej "starej".

nie działa bo nie przyjrzałeś się im i nie przekopiowałeś tylko zerknąłeś i próbowałeś wkomponować to w programie samemu zostawiając linijkę this.Controls.Add(tekst); niezmienioną

nie ma najmniejszej szansy żeby kontrolka dodawana do dlg.Controls przeskoczyła do this.Controls

0

Ok już zrozumiałem i zrezygnowałem z dynamicznego dodawania kontrolek. Już pododawałem normalnie.

Jednak mam kolejny problem.

W projekcie posiadam osobny plik klasy o nazwie ParametrySieci.CS, który wygląda tak:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication2
{
    public class ParametrySieci
    {

        public double napiecie;
        //public double cmin;
        //public double cmax;
        //public double f;
       // public double mz;  
    }

}
 

W MainForm(moja forma główna) tworzę nową formę FormIPN, na której użytkownik będzie pracował, w ten sposób:

 public void nowyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
            TaskDialog td = new TaskDialog();
            td.Caption = "Wybór sposobu uziemienia punktu neutralnego";

            TaskDialogCommandLink cl1 = new TaskDialogCommandLink("cl1", "Izolowany punkt neutralny");
            cl1.Click += (s, d) => choice = 1;
            cl1.Click += (s, d) => td.Close(TaskDialogResult.Close); ;
            td.Controls.Add(cl1);

            TaskDialogCommandLink cl2 = new TaskDialogCommandLink("cl2", "Uziemienie przez rezystor pierwotny");
            cl2.Click += (s, d) => choice = 2;
            cl2.Click += (s, d) => td.Close(TaskDialogResult.Close); ;
            td.Controls.Add(cl2);


            TaskDialogCommandLink clc = new TaskDialogCommandLink("clc", "Anuluj");
            clc.Click += (s, ev) => td.Close(TaskDialogResult.Close); ;
            td.Controls.Add(clc);

            td.InstructionText = "Wybierz sposób uziemienia punktu neutralnego transformatora SN, jaki chcesz przyjąć: ";
            TaskDialogResult tdr = td.Show();


            if (choice == 1)
            {
                //FormIPN Form2 = new FormIPN();
                //Form2.MdiParent = this;
                //Form2.Show();
                if (MessageBox.Show("Wybrano izolowany punkt neutralny.", " ", MessageBoxButtons.OK, MessageBoxIcon.Information) == DialogResult.OK)
                {
                    FormIPN Form2 = new FormIPN();
                    Form2.MdiParent = this;
                    Form2.Show();
                    nowyToolStripMenuItem.Enabled = false;
                }
            }
           

A z kolei w formie FormIPN otwieram okno dialogowe, z którego będę chciał pobrać zmienną:

 namespace WindowsFormsApplication2
{
    public partial class FormIPN : Form
    {
        ParametrySieci parametry = new ParametrySieci();

        public FormIPN()
        {
            InitializeComponent();
            label1.Text = parametry.napiecie.ToString();
        }

        public void Form2_Load(object sender, EventArgs e)
        {
            
        }

        public void parametrysieci_Click(object sender, EventArgs e)
        {
            FormParametrySieci ps = new FormParametrySieci();
            ps.ShowDialog();
        }
    }
}

Okno dialogowe wygląda tak:

 namespace WindowsFormsApplication2
{
    public partial class FormParametrySieci : Form
    {
      

        public FormParametrySieci()
        {
            InitializeComponent();
        }

        private void FormParametrySieci_Load(object sender, EventArgs e)
        {

        }

        public void OK_Click(object sender, EventArgs e)
        {
            bool bVal1 = Double.TryParse(textBox1.Text, out napiecie);


            if (bVal1)
            {
                MessageBox.Show("Wprowadzono", "Informacja", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.Close();
            }
            else
            {
                MessageBox.Show("Wprowadzone dane są niepoprawne lub ich brak.", "Uwaga!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void Anuluj_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }

}

Czy może ktoś mi podpowiedzieć, jak z okna dialogowego FormParametrySieci pobrać wartość z textBox1 i przypisać ją do zmiennej napięcie, zadeklarowanej w pliku klasy ParametrySieci.cs, oraz wyświetlić tę wartość w FormIPN. Chodzi mi o to, aby użytkownik mógł wpisać jakąś tam wartość, i ona została przypisana do zmiennej w klasie ParametrySieci i widoczna w FormIPN. Dla testu umieściłem tę linijkę:

 label1.Text = parametry.napiecie.ToString();

Próbowałem na milion sposobów, tworzyłem obiekt klasy ParametrySieci w FormIPN, i obiekt klasy FormParametrySieci. Za każdym razem nie działa. Jeżeli w klasie przypiszę do zmiennej napiecie np =200, to w FormIPN wyświetla się 200 tak jak powinno, jednak nie mogę dojść do tego jak zmienić wartość tej zmiennej właśnie z poziomu okna dialogowego.. Błagam help :F

1

Nie za bardzo chce mi się to wszystko czytać ani analizować, ale mam nadzieję że zrozumiałem pytanie i to pomoże:

Żeby zrobić okienko dialogowe z którego pobierasz dane, tworzysz normalnie nową formę, kładziesz na niej dwa przyciski
Dla jednego ustawiasz własność DialogResult na OK, w drugim na Cancel

Dodajesz do formy pole

public String wybor; // przykładowo String, może być cokolwiek innego

w onclick przycisku OK dajesz:

wybor = TextBox1.Text; // przykładowo

nie musisz dawać Close() bo okienko samo się zamknie gdy się kliknie przycisk z ustawionym DialogResult

potem na głównej formie gdzie chcesz odbierać dane piszesz:

using (var dialogowe = new FormDialogowy())
{
    if (dialogowe.ShowDialog() == DialogResult.OK) // jeśli kliknięto OK
    {
        lokalnaZmienna = dialogowe.wybor;
        MessageBox.Show(lokalnaZmienna); // przykładowo
    }
}

i tyle

walidację danych z textboxa możesz albo zrobić w głównym wątku (otwierając potem okno dialogowe ponownie), albo w ogóle zdezaktywować przycisk "OK" dopóki wartość w inpucie nie będzie dobra
ewentualnie możesz sprawdzać w onclicku i ustawić ręcznie DialogResult = DialogResult.None żeby forma się nie zamknęła

0

Zrobiłem tak jak radzisz. Kod wygląda tak:

namespace WindowsFormsApplication2
{
    public partial class FormIPN : Form
    {
        public string lokalnazmienna;
        public FormIPN()
        {
            InitializeComponent();
        }

        public void Form2_Load(object sender, EventArgs e)
        {
            
        }

        public void parametrysieci_Click(object sender, EventArgs e)
        {
            using (var ps = new FormParametrySieci())
            {
                if (ps.ShowDialog() == DialogResult.OK)
                {
                    lokalnazmienna = ps.wybor;
                    MessageBox.Show(lokalnazmienna);
                }
            }
        }
    }
}
 

I w oknie dialogowym:

 namespace WindowsFormsApplication2
{
    public partial class FormParametrySieci : Form
    {
        public String wybor;
        public FormParametrySieci()
        {
            InitializeComponent();
        }

        private void FormParametrySieci_Load(object sender, EventArgs e)
        {

        }

        public void OK_Click(object sender, EventArgs e)
        {
            wybor = textBox1.Text;
        }

        private void Anuluj_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }

}

I mimo to nie działa. W messsagebox'ie nie pojawia się to co wpisałem w textbox'a.

0

FormParametrySieci prawdopodobnie zapomniałeś ustawić na buttonie DialogResult na OK. Wiec możesz to zrobić poprzez designer i propertis buttona, albo w kodzie dodaj:

this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
0

Nie zapomniałem, jest ustawiony. Poza tym gdyby nie był to messagebox by się w ogóle nie pojawiał, a sie pojawia tylko pusty.

0
maciaba napisał(a):

Nie zapomniałem, jest ustawiony. Poza tym gdyby nie był to messagebox by się w ogóle nie pojawiał, a sie pojawia tylko pusty.

bardzo dziwne, jedyne wytłumaczenie jakie mi przychodzi na myśl to że masz więcej inputów (być może jeden zakrywa drugi) i wpisujesz nie do tego co trzeba

0

Więcej inputów tzn? Mam tylko jednego textboxa w oknie dialogowym.

Może powinienem dodać jakieś Referencje jeszcze? Albo argumenty formularza?

0

spakuj cały projekt w zipa i daj jako załącznik

0

Bardzo proszę. Dzięki za chęci

1

nie przypisałeś wydarzenia onclick
kliknij dwa razy na przycisk a zobaczysz że utworzy się drugie wydarzenie, a tamto w kodzie nie jest wykorzystane

0

Jak to się stało? Przecież normalnie przeszedłem do zakładki Events i kliknalem dwa razy na Click. Jak do tego doszedłes?

Bez sensu. No nic, w każdym razie w KOŃCU działa. Wielkie dzięki :)

A jeszcze jakbyś mi podpowiedział jak przekonwertować to co wpiszę do textboxa do double?

Wartości wpisywane do textboxów będą liczbami.

0
double a = Convert.ToDouble(textBox1.Text);
double b = double.Parse(textBox1.Text);
1

W poprzednich postach miałeś już zamianę stringa na double, ale proponuję zamienić TextBox na kontrolkę NumericUpDown - wtedy będzie można scrollem na myszce zmieniać wartość, aplikacja bez dodatkowego kodu nie pozwoli na wpisanie czegoś innego niż liczby i nie musisz niczego konwertować, wystarczy rzutować:

wybor = (double)numericUpDown1.Value;

pamiętaj o ustawieniu Minimum, Maximum, DecimalPlaces i Increment (żeby ustawić o ile będzie się zmieniać wartość przy użyciu scrolla lub przycisków)

0

Te rozwiązanie się raczej nie sprawdzi niestety. Ale w końcu się udało.

Jeszcze jedno pytanie, czy ja dobrze rozumiem, ten kod:

 if (ps.ShowDialog() == DialogResult.OK)
                {
                    
                    parametry.napiecie = ps.U;
                    MessageBox.Show(parametry.napiecie.ToString(), "cos tam");
                }

odpowiada za nadanie nowej wartości zmiennej napiecie z klasy ParametrySieci.cs. Czy teraz w dowolnym miejscu w tym formularzu (FormIPN) będę mógł wywoływać tą zmienną (która ma przypisaną wartość przez użytkownika) np. do obliczeń?

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