dostęp do metod klasy z obiektów formatki

0

Witam,
od razu zaznaczam, że stawiam pierwsze kroki w C#, przerabiam Michelsona i Liberty.
W ramach ćwiczeń C# 2008 popełniłem coś takiego, zadeklarowałem klasę 'NowaF':

namespace WFA_001
{
    public class NowaF : Form
    {
        public Form F0;

        public NowaF(ref Form F1)
        {
            F0 = F1;
        }


        public void NowaF_Start()
        {
            F0.Show();
        }

        public void NowaF_End()
        {
            F0.Close();
        }
    }
}

Klasa przejmuje referencję do formatki i ma za zadanie sterować wyświetlaniem i zamykaniem tej formatki - tak sobie wymyśliłem.
Skompilowało sie, myślę sobie 'dobrze jest'.

Formatka 'Form1' zawiera dwa buttony i kod tak wygląda:

namespace WFA_001
{
    public partial class Form1 : Form
    {       
        public Form1()
        {
            InitializeComponent();

            button1.Text = "Otwórz okno";
            Form Fx = new Form1();
            NowaF NF = new NowaF(ref Fx);
        }
        
        public void button1_Click(object sender, EventArgs e)        
        {                                    
                NF.NowaF_Start();     //NF jest zaznaczony na czerwono - i tego nie rozumiem?          
        }  
       
        public void button2_Click(object sender, EventArgs e)
        {
              NF.NowaF_End();    //NF jest zaznaczony na czerwono - i tego nie rozumiem?   
        }
        
     }
}

Nie rozumiem, dlaczego kompilator się czepia wywołania metod obiektu 'NF' utworzonego z klasy 'NowaF' w konstruktorze 'Form1'?
Co ciekawe, dla mnie, jeśli stworzę obiekt 'NF' z poziomu buttona:

public void button1_Click(object sender, EventArgs e)        
        {
                Form Fx = new Form1();
                NowaF NF = new NowaF(ref Fx);
                NF.NowaF_Start();     //ten kod się kompiluje i działa!           
        }  

To, po kliknięciu w button okno się otwiera.
Czegoś istotnego tu chyba nie rozumiem i w tym kontekście się (uprzejmie) pytam.
Jestem na formatce 'F0' będącej referencją do 'Form1', czyli jestem de facto na 'Form1' sterowanej z poziomu klasy 'NowaF' - i o to mi chodziło w tym moim ćwiczeniu.

Pozdrawiam.

0

Zmienna NF istnieje tylko w obrębie konstruktora klasy Form1. Po wyjściu z niego ta zmienna nie jest nigdzie indziej widoczna, ponieważ nie jest to zmienna składowa klasy, a zmienna lokalna. Zadeklaruj sobie tą zmienną jako pole w klasie i będzie ok.

0
public NowaF(ref Form F1)

Nie potrzeba ref Form. Zostaw samo Form.

0
stfu napisał(a)

Zmienna NF istnieje tylko w obrębie konstruktora klasy Form1. Po wyjściu z niego ta zmienna nie jest nigdzie indziej widoczna, ponieważ nie jest to zmienna składowa klasy, a zmienna lokalna. Zadeklaruj sobie tą zmienną jako pole w klasie i będzie ok.

Dzięki.
A mógłbyś to napisać i zamieścić?

0

Zrobiłem tak:

public partial class Form1 : Form
    {
        public NowaF NF1;
      
        public Form1()
        {
            InitializeComponent();

            button1.Text = "Otwórz okno";
            Form Fx = new Form1();
            NowaF NF = new NowaF(ref Fx);
            NF1 = NF;
        }
        
        public void button1_Click(object sender, EventArgs e)        
        {               
                button1.Text = "Otwórz okno";
                NF1.NowaF_Start();                
        }  

Kompilator puszcza, ale debager się czepia i nie uruchamia się.
"An unhandled exception of type 'System.StackOverflowException' occurred in System.Windows.Forms.dll"

tak też debager blokuje:

public partial class Form1 : Form
    {
        public NowaF NF1;
      
        public Form1()
        {
            InitializeComponent();

            button1.Text = "Otwórz okno";
            Form Fx = new Form1();
            NF1 = new NowaF(ref Fx);
            
        }
        
        public void button1_Click(object sender, EventArgs e)        
        {               
                button1.Text = "Otwórz okno";
                NF1.NowaF_Start();                
        }
0

Mam nadzieję, że czytałeś o zmiennych lokalnych, polach klas, stałych itd., ale nie zrozumiałeś. A jak nie czytałeś, to radzę poczytać.

Popatrz co robisz w konstruktorze:

public Form1()
{
	InitializeComponent();
	button1.Text = "Otwórz okno";
	Form Fx = new Form1();	// tutaj tworzysz nowy obiekt typu Form1 i nazywasz go Fx (zgadnij co robi ten konstruktor?)
	NF1 = new NowaF(ref Fx);	
}

Teraz popatrz jakiego konstruktora używasz i pomyśl co się wywoła (a najlepiej to skorzystaj z debuger'a i przechodź krok po kroku "wchodząc" do tego konstruktora).

Powinieneś zrobić tak w konstruktorze:

//...
NF1 = new NowaF(this);
//...

uprzednio zmieniając definicję konstruktora NowaF i wywalając z niej parametr ref.

0

Obserwując działanie mojego programu z ćwiczenia, widzę, że zrobiłem klasę, która odpowiada za zgaszenie formatki - jakby tego nie dało się zrobić jedną prostą i fundamentalną instrukcją 'exit program' umieszczoną w obsłudze zdarzenia kliknięcia w button.
Idei ćwiczenia nie zrealizowałem, miało się otwierać nowe okno (na wzór Form1) po kliknięciu w button1 na startowej formatce Form1, potem poprzez kliknięcie w button2 z otwartego okna, okno to miało się zamykać, a na ekranie pozostać czyste Form1. Doszedłem do tego, że otwierałem nowe okno, ale nie umiałem je zamknąć z buttona.
Byłbym wdzięczny, za sugestie, jak to załatwić?

0
paco11 napisał(a)

Idei ćwiczenia nie zrealizowałem, miało się otwierać nowe okno (na wzór Form1) po kliknięciu w button1 na startowej formatce Form1, potem poprzez kliknięcie w button2 z otwartego okna, okno to miało się zamykać, a na ekranie pozostać czyste Form1. Doszedłem do tego, że otwierałem nowe okno, ale nie umiałem je zamknąć z buttona.
Byłbym wdzięczny, za sugestie, jak to załatwić?

W button1_Click utwórz obiekt okna i go wyświetl metodą Show, a w button2_Click zamknij okno metodą Close. To są w sumie trzy linijki kodu i tego nie ma jak zepsuć.

0

Serio nie udało Ci się tego napisać?

public partial class Form1 : Form
{ 
    public Form1()
    {
        InitializeComponent();            
    }
        
    private void button1_Click(object sender, EventArgs e)        
    {               
        new Form2().Show();
    }    
}
public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();            
    }
        
    private void button2_Click(object sender, EventArgs e)        
    {               
        this.Close();
    }
}
0

Somekind: Dziekuję za przykład. To była lekcja słowa kluczowego 'this', zaczyna mi się to baaardzo podobać.
Nie muszę deklarować Form2, bo i po co?

0

this jest tak naprawdę opcjonalne, ja go używam, bo taki zapis po prostu ładnie wygląda. Równie dobrze mógłbyś napisać samo Close(), bo jest to metoda Form, a więc i każdego utworzonego przez Ciebie formularza.

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