Aplikacja wielookienkowa

Aplikacja wielookienkowa może pracować w dwóch trybach:

Rodzaj trybu pracy okna aplikacji wielookienkowej zależy od tego czy wartość this.IsMdiContainer formatki okna nadrzędnego ustawimy na true. Ta właściwość oznacza, że jest zdefiniowane okno nadrzędne- ojciec

aplikacja MDI. Visual Studio C#

Możemy to zrobić w oknie właściwości tworzonej formatki okna (wygodniejsze rozwiązanie).

aplikacja wielookienkowa MDI. Visual Studio C#

Lub w kodzie programu w momencie ładowania głównego okna (zdarzenie Load)

Wskazówka:


private void Form1_Load(object sender, EventArgs e)
 {
	 this.IsMdiContainer = true;
 }

Układ okien potomnych umieszczonych wewnątrz okna rodzica

Ten tryb pracy uzyskuje się w oknach potomnych gdy w momencie tworzenia okna potomnego przypiszemy właściciela- rodzica

Wskazówka:


f.MdiParent = this;//jest w obszarze okna rodzica

Każde okno, z tak przypisanym rodzicem będzie tworzone wewnątrz okna rodzica

tworzonie wewnątrz okna rodzica MDI. Visual Studio C#

Układ okien potomnych umieszczonych poza oknem rodzica

Ten tryb pracy uzyskuje się w oknach potomnych gdy w momencie tworzenia okna potomnego nie przypiszemy właściciela- rodzica

Wskazówka:


f.MdiParent = null;//nie jest w obszarze okna rodzica

Okna potomne umieszczone są poza obszarem rodzica

tworzonie poza oknnem rodzica MDI. Visual Studio C#

Cel: Napisz aplikację wielookienkową zawierającą menu, z którego można otwierać nowe okna.

aplikacja MDI Visual studio C#

Krok 1. Układ komponentów

Uwaga: Komponent Form nie jest dostępny w oknie Przybornika. Nowy formularza (klasa Form) dodaję się z menu Projekt/ Dodaj formularz Windows Forms

Krok 3. Ustalamy nadrzędną formatkę- okno główne

W aktywnej formatce we właściwościach okna wybieramy opcję kontenera MDI (IsMdiContainer ustawiamy na True)

IsMdiContainer Visual Studio C#

Krok 3. Dodajemy nowe formatki okien

Przechodzimy do opcji Projekt głównego menu środowiska Visual Studio i wybieramy opcję Dodaj formularz Windows Forms

Dodaj formularz Windows Forms

W otrzymanym oknie dialogowym wykonujemy poniższe czynności

dodani eokna dziecka MDI Visual studio C#

Nazwę można zmienić (nie wolno używać spacji), ale wygodniej jest zachować proponowaną.

Czynności powtarzamy dla wszystkich dodawanych okien w tworzonej aplikacji. Prawidłowo wykonanie tego kroku powinno dać widok kolejnych formularzy formatek okien

formularz wielookienkowy visual studio c#

Krok 4. Tworzymy menu okna głównego

Menu okna głównego posłuży nam do otwierania kolejnych okien. Dodatkowo przypiszemy im klawisze skrótu. W obszarze okna głównego osadzamy komponent MenuStrip i tworzymy menu

Menu okna głównego

Dodanie klawiszy skrótów opcjom menu wykonujemy we właściwościach aktywnego ToolStripMenuItem tak jak pokazuje to poniższa ilustracja

Dodanie klawiszy skrótów visual studio c#

Efekt końcowy przypisanych klawiszy skrótów przedstawi się jak poniżej

menu okna klawisze skrótów visula studio c#

Krok 5. Deklaracja zmiennych okien formatek

Do dalszych przewidywanych celów projektowych działania aplikacji wielookienkowej zmiennym nadamy charakter publiczny

Wskazówka:


public partial class Form1 : Form
{
	public Form2 form2;
	public Form3 form3;
	public Form4 form4;

	public Form1()
	{
		InitializeComponent();
	}

Krok 6. Wywołanie okna formatki

Jest kilka możliwości rozwiązania utworzenia okna formatki podrzędnej tak zwanego dziecka okna głównego. Wybór metody rozwiązania będzie wpływać na sposób przesyłania danych pomiędzy oknami. Poniżej przedstawię sposób otwarcia jednego konkretnego okna z jednoczesnym zabezpieczeniem przed wielokrotnym powieleniem. Zdarzenie będzie obsługiwane w metodzie Click komponentu ToolStripMenuItem

Wskazówka:


private void Okno1ToolStripMenuItem_Click(object sender, EventArgs e)
{
	//otwarcie jednego konkretnego okna
	//zabezpiecz przed wielokrotnym powielaniem tworzenia okna
	if (form2 == null)
	{
		form2 = new Form2();
		form2.MdiParent = this;
		form2.Tag = "okno1";
		form2.FormClosed += new FormClosedEventHandler(zwolnijUchwyt);
		form2.Show();
	}
	else form2.Activate();
}

Uwaga. Powyższa metoda zawiera nadpisanie standardowej funkcji zamykającej FormClosed. Jest to konieczne, ponieważ musimy zwolnic uchwyt do zmiennej reprezentującej okno. Jeżeli byśmy tego nie zrobili, to powyższe rozwiązanie zadziałałoby jeden raz, dopóki byśmy nie zamknęli wywołanego okna dziecka w działającej aplikacji.

Postać funkcji, którą musimy nadpisać ma postać (przewidujemy rozwiązanie uniwersalne dla wszystkich utworzonych podokien wywołanych tą metodą):


Wskazówka:


public void zwolnijUchwyt(object sender, FormClosedEventArgs e)
{
	Form f =sender as Form;
	switch (f.Tag.ToString())
	{
		case "okno1": form2 = null; break;
		case "okno2": form3 = null; break;
		case "okno3": form4 = null; break;
	}
}

Skompiluj i uruchom aplikację sprawdzając jej działanie.

Krok 7. Uniwersalne wywołanie okna dla metody pierwszej

Zastosowanie uniwersalnej funkcji skraca kod programu. Kod funkcji, którą będziemy mogli zastosować dla dowolnego okna musi zawierać dwa parametry- argumenty. Parametr klasy Form i parametr łańcucha znaków string dla właściwości Tag tworzonego okna.

Wskazówka:


//uniwersalna funkcja otwierająca nowe okno dla metody pierwszej
public void RobOkno(Form f, string tag)
{
	f.MdiParent = this;
	f.Tag = tag;
	f.FormClosed += new FormClosedEventHandler(zwolnijUchwyt);
	f.Show();
	f.Activate();
}

Użycie powyższej funkcji w obsłudze komunikatu zdarzenia Click (dopinamy je we właściwościach w metodzie Click komponentu ToolStripMenuItem) jest następujące


Wskazówka:


private void Okno2ToolStripMenuItem_Click(object sender, EventArgs e)
{
	//zabezpiecz przed wielokrotnym powielaniem tworzenia okna
	if (form3 == null) RobOkno(form3 = new Form3(), "okno2");
	else form3.Activate();
}

Skompiluj program i sprawdź efekt działania. Prawidłowo działająca na tym etapie aplikacja pozwoli na wielokrotne otwieranie i zamykanie okien dzieci. Przedstawia to poniższa ilustracja

aplikacja wielookienkowa visual studio c#

Metoda II wywołania okien w aplikacji wielookienkowej

Ta metoda opiera się na zastosowaniu instancji do klasy okna dziecka. Nie wymaga nadpisywania zdarzenia zamknięcia okna. Zwolnienie uchwytu instancji wykonuje się w każdym oknie z osobna w metodzie FormClosed

Krok 1. Rozbudowanie opcji menu

Menu głównego okna należy rozbudować o kolejne opcje

Menu głównego okna instancja okna visuala studio c#

Krok 2. Dodajemy kolejne formatki okien dzieci

Powtarzamy czynności z kroku 3 metody I

Krok 3. Deklarujemy instancję klasy okna oraz funkcję zwracającą uchwyt do klasy okna

Zmienna instancji klasy musi być prywatna, a funkcja ją zwracająca publiczna. Obie muszą być statyczne, co dla kompilatora oznacza, że nie będą nadpisywane w dalszym rozwijaniu kodu .projektu. Każda nowo dodana klasa okna dziecka powinna zawierać ten kod


Wskazówka:


public partial class Form7 : Form
{
	private static Form7 instancja;
	
	public static Form7 Instancja
	{
		get{
			if (instancja == null) instancja = new Form7();
			return instancja;
		}
	}

Krok 4. Zwolnienie uchwytu instancji

Zwolnienie uchwytu instancji wykonuje się w każdym oknie z osobna w metodzie FormClosed

Wskazówka:


private void Form7_FormClosed(object sender, FormClosedEventArgs e)
{
	instancja = null;
}

Kompilacja programu na tym etapie nie pozwoli otworzyć dodanych okien ale umożliwi sprawdzenie czy kod nie zawiera błędów

Krok 5. Uniwersalna funkcja tworząca instancję okna

Przechodzimy do zakładki kodu formatki okna głównego. Tworzymy dwuargumentową funkcję tworząca okno dziecka

Wskazówka:


//Uniwersalna funkcja tworząca instancję okna metoda druga
void RobOknoInstancji(Form f,string tag)
{
	f.MdiParent = this;
	f.Tag = tag;
	f.Show();
	f.Activate();
}

Zwróć uwagę, że ciało funkcji nie zwiera warunku zabezpieczającego przed wielokrotnym konstruowaniem tego samego okna dziecka. Warunek ten już został w prowadzony w publicznej statycznej funkcji Instancja w kodzie każdej tak dodawanej formatki.

Krok 6. Wywołanie okna poprzez instancję klasy

Użycie powyższej funkcji wymaga obsługę komunikatu zdarzenia Click (dopinamy je we właściwościach w metodzie Click komponentu ToolStripMenuItem)


Wskazówka:


private void OknoInstancja3ToolStripMenuItem_Click(object sender, EventArgs e)
{
	RobOknoInstancji(Form7.Instancja, "OknoInstnacj3");
	//przykład wypełnienia metody Text instnacji nowego okna
	Form7.Instancja.Text = "Okno Instancji 3";
	Form7.Instancja.Width = this.Width / 2;
	Form7.Instancja.Height = this.Height / 2;
}

Powyższa funkcja zawiera kilka przykładowych odwołań do podstawowych właściwości wywołanych okien dzieci.

Po skompilowaniu i uruchomieniu projektu prawidłowo działająca aplikacja wygląda jak poniżej

MDI Visual Studio C#

Pełny kod pliku okna głównego Form1.cs

Wskazówka:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace wieleOkien
{
    public partial class Form1 : Form
    {
        public Form2 form2;
        public Form3 form3;
        public Form4 form4;

        public Form1()
        {
            InitializeComponent();
        }

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

        private void Okno1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //otwarcie jednego konkretnego okna
            //zabezpiecz przed wielokrotnym powielaniem tworzenia okna
            if (form2 == null)
            {
                form2 = new Form2();
                form2.MdiParent = this;
                form2.Tag = "okno1";
                form2.FormClosed += new FormClosedEventHandler(zwolnijUchwyt);
                form2.Show();
            }
            else form2.Activate();
        }
        //uniwersalna funkcja otwierająca nowe okno dla metody pierwszej
        public void RobOkno(Form f, string tag)
        {
            f.MdiParent = this;
            f.Tag = tag;
            f.FormClosed += new FormClosedEventHandler(zwolnijUchwyt);
            f.Show();
            f.Activate();
        }

        public void zwolnijUchwyt(object sender, FormClosedEventArgs e)
        {
            Form f =sender as Form;
            switch (f.Tag.ToString())
            {
                case "okno1": form2 = null; break;
                case "okno2": form3 = null; break;
                case "okno3": form4 = null; break;
            }
        }

        private void Okno2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //zabezpiecz przed wielokrotnym powielaniem tworzenia okna
            if (form3 == null) RobOkno(form3 = new Form3(), "okno2");
            else form3.Activate();
        }

        private void Okno3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //zabezpiecz przed wielokrotnym powielaniem tworzenia okna
            if (form4 == null) RobOkno(form4 = new Form4(), "okno3");
            else form4.Activate();
        }
        //Uniwersalna funkcja tworząca instancję okna metoda druga
        void RobOknoInstancji(Form f,string tag)
        {
            f.MdiParent = this;
            f.Tag = tag;
            f.Show();
            f.Activate();
        }

        private void OknoInstancja1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RobOknoInstancji(Form5.Instancja, "OknoInstnacj1");
            //przykład wypełnienia metody Text instnacji nowego okna
            Form5.Instancja.Text = "Okno Instancji 1";
        }

        private void OknoInstancja2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RobOknoInstancji(Form6.Instancja, "OknoInstnacj2");
            //przykład wypełnienia metody Text instnacji nowego okna
            Form6.Instancja.Text = "Okno Instancji 2";
            Form6.Instancja.Width = this.Width / 2;
            Form6.Instancja.Height = this.Height / 2;
        }

        private void OknoInstancja3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RobOknoInstancji(Form7.Instancja, "OknoInstnacj3");
            //przykład wypełnienia metody Text instnacji nowego okna
            Form7.Instancja.Text = "Okno Instancji 3";
            Form7.Instancja.Width = this.Width / 2;
            Form7.Instancja.Height = this.Height / 2;
        }
    }
}

Pełny kod jednego z okien potomnych wywoływanych metodą I

Wskazówka:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace wieleOkien
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            //rzutuj na uchwyt ojca
            Form1 f = (Form1)this.MdiParent;
            if (f.form3 == null) {
                f.form3 = new Form3();
                f.RobOkno(f.form3, "okno2");
                //lub taką konstrukcję
                //f.RobOkno(f.form3 = new Form3(), f, "okno2");
            }
            else f.form3.Activate();
        }

        private void Button2_Click(object sender, EventArgs e)
        {
            //rzutuj na uchwyt ojca
            Form1 f = (Form1)this.MdiParent;
            if (f.form4 == null)f.RobOkno(f.form4 = new Form4(), "okno3");
            else f.form4.Activate();
        }
    }
}

Pełny kod jednego z okien potomnych wywoływanych metodą II (przez instancję)

Wskazówka:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace wieleOkien
{
    public partial class Form5 : Form
    {
        private static Form5 instancja;
        public static Form5 Instancja {
            get
            {
                //zabezpiecz przed wielokrotnym tworzeniem klasy okna
                if (instancja == null) instancja = new Form5();
                return instancja;
            }
        }
            

        public Form5()
        {
            InitializeComponent();
        }

        private void Form5_FormClosed(object sender, FormClosedEventArgs e)
        {
            //zwolnij uchwyt instancji klasy w momencie zamykania okna
            instancja = null;
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            Form6.Instancja.MdiParent = this.MdiParent;
            Form6.Instancja.Text="Okno II otwarte z okna I";
            Form6.Instancja.Show();
            Form6.Instancja.Activate();
        }

        private void Button2_Click(object sender, EventArgs e)
        {
            Form7.Instancja.MdiParent = this.MdiParent;
            Form7.Instancja.Text = "Okno III otwarte z okna I";
            Form7.Instancja.Show();
            Form6.Instancja.Activate();
        }
    }
}
Układ okresowy- kod qr
Układ okresowy

Układ okresowy pierwiastków- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Alkomat- wirtualny test kod qr
Alkomat- wirtualny test

Alkomat- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Taklarz- olinowanie stałe kod qr
Olinowanie stałe- kalkulator średnic

Olinowanie stałe- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
przepis na gogfry

Przepis na gofry

zobacz
przepis na bitą śmietanę

Przepis na bitą śmietanę

zobacz