• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Przekazywanie danych między formularzami C# Windows Forms

Object Storage Arubacloud
0 głosów
1,115 wizyt
pytanie zadane 2 czerwca 2019 w C# przez MakaBresk Obywatel (1,060 p.)
zamknięte 8 czerwca 2019 przez MakaBresk

Mam do napisania program typu notatnik. Ma odczytać zawartość pliku, pozwolić na jego edycję i zapis nowo wprowadzonych danych. Jak dotąd stworzyłem 3 formularze.
1-wszy zawiera główne menu: Plik: Otwórz, Zapisz. Kliknięcie Otwórz wywołuje nowe okno formularza o nazwie Otworz.cs

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 Zadanie_11
{
    // Ikony dla menu pobrane z www.flaticon.com

    public partial class Notepad : Form
    {
        public Notepad(string strTextBox)
        {
            InitializeComponent();
            textBox1.Text = strTextBox;
        }

        private void OtwórzToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Open open = new Open(); // Tworzenie instacji formularza podrzędnego
            open.Show(); // Wyświetlenie formularza podrzędnego
        }

        private void ZapiszToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Save save = new Save(); // Tworzenie instacji formularza podrzędnego
            save.Show(); // Wyświetlenie formularza podrzędnego
        }
    }
}

2-gi Otworz.cs zawiera textbox, w którym zapisuje się ścieżka do pliku oraz przycisk Wczytaj, którego wciśnięcie powoduje uruchomienie okna wyboru pliku, który chcemy otworzyć.

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 Zadanie_11
{
    public partial class Open : Form
    {
        public Open()
        {
            InitializeComponent();
        }

        private void Wczytaj_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog(); // Tworzenie instacji dla otwarcia pliku

            if (openFileDialog.ShowDialog() == DialogResult.OK) // Sprawdzenie czy plik został pomyślnie otwarty ?
            {
                try
                {
                    textBox1.Text = openFileDialog.FileName; // Wyświetlenie ścieżki do pliku w kontrolce textBox.

                    Notepad notepad = new Notepad(textBox1.Text);
                     // PROBLEM Z PRZEKAZANIEM ŚCIEŻKI do pliku Z OPEN.cs do NOTEPAD.cs 

                }
                catch (Exception ex) // Obsługa wyjątku błąd przy otwarciu pliku
                {
                    MessageBox.Show("Błąd wyboru pliku: " + ex.Message);
                }
            }
        }
    }
}

 

3-ci jest aktualnie pusty.

 

Mam problem przy przekazywaniu tej ścieżki z textbox (formularz Otworz.cs) do formularza z głównym menu o nazwie Notatnik.cs. Wyrzuca błąd: There is no argument given that corresponds to the required formal parameter

Kod zawierający błąd:

Otworz.cs

Notepad notepad = new Notepad(textBox1.Text);


Notatnik.cs

public Notepad(string strTextBox)
        {
            InitializeComponent();
            textBox1.Text = strTextBox;
        }

 

komentarz zamknięcia: Problem rozwiązany
komentarz 4 czerwca 2019 przez DarthMazut Bywalec (2,990 p.)
Nie umiem Ci powiedzieć dlaczego tak się dzieje - konstruktor Notepada chce stringa i stringa dostaje, powinno działać; natomiast żeby mój komentarz miał jakąkolwiek wartość to podpowiem Ci że ta linijka:

openFileDialog.ShowDialog() == DialogResult.OK

nie sprawdza czy plik został pomyślnie otwarty, tylko czy zakończyłeś dialog poleceniem otwórz; OpenDialog nie otwiera plików a jedynie zwraca Ci do nich ścieżki.
komentarz 6 czerwca 2019 przez MakaBresk Obywatel (1,060 p.)

Dzisiaj się o tym dowiedziałem na zajęciach ;) Co do zadania nauczyciel podpowiedział mi rozwiązanie tego problemu.

Jeżeli czegoś nie pomyliłem to rozwiązanie powinno wyglądać tak: 

Notepad.cs

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 Zadanie_11
{
    // Ikony dla menu pobrane z www.flaticon.com
 
    public partial class Notepad : Form
    {
        public Notepad()
        {
            InitializeComponent();
        }

        public string path;
 
        private void OtwórzToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Open open = new Open(this); // Tworzenie instacji formularza podrzędnego
            open.Show(); // Wyświetlenie formularza podrzędnego
        }
 
        private void ZapiszToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Save save = new Save(); // Tworzenie instacji formularza podrzędnego
            save.Show(); // Wyświetlenie formularza podrzędnego
        }
    }
}

Open.cs

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 Zadanie_11
{
    public partial class Open : Form
    {
        public Open(string path)
        {
            InitializeComponent();
            this.path = path;
        }

        public path;
 
        private void Wczytaj_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog(); // Tworzenie instacji dla otwarcia pliku
 
            if (openFileDialog.ShowDialog() == DialogResult.OK) // Sprawdzenie czy został wciśnięty klawisz Otwórz
            {
                try
                {
                    path.path = openFileDialog.FileName; // Wprowadzenie ścieżki do pliku do zmiennej
                catch (Exception ex) // Obsługa wyjątku błąd przy otwarciu pliku
                {
                    MessageBox.Show("Błąd wyboru pliku: " + ex.Message);
                }
            }
        }
    }
}

 

Jednak później napotkałem kolejny problem.

Tzn. nie wiem kiedy mam przypisać przekazany parametr do textBox.Text. Nauczyciel doradził mi abym to zrobił po wywołaniu formularza Open jednak jest to zbyt wcześnie.

Czy można napisać funkcję, która zostanie wywołana przez inny formularz?

np. Open wywołuje funkcję w Notepad, w tejże funkcji zapisuje przekazany parametr do textBox1.Text.

 

1 odpowiedź

+1 głos
odpowiedź 7 czerwca 2019 przez DarthMazut Bywalec (2,990 p.)
wybrane 8 czerwca 2019 przez MakaBresk
 
Najlepsza

Cześć smiley,
Po pierwsze kod który przedstawiłeś zawiera poważne błędy:

Open open = new Open(this);
tworzysz nową instancję formy Open i przekazujesz jej w konstruktor bieżącą formę; z tego co przeglądnąłem w dokumentacji konstruktor klasy Form nie jest przeciążony aby przyjmować obiekty typu Form. Nasuwa mi się pytanie, czy masz wogóle dostęp
do IDE np. Visual Studio i jeśli tak czy nie wskazuje Ci na błędy w tym kodzie?

public path;
brakuje typu, pewnie chodziło Ci o public string path;

path.path = openFileDialog.FileName;
chyba chodziło o "this.path", ale w tym kontekście nie musisz używać "this", wystarczy samo path.

Nauczyciel Ci doradził i masz nowy kod - w porządku - ale co z wcześniejszym problemem, wiadomo dlaczego nie można było przekazać stringa w konstruktor notepada? Problem był nietrywialny stąd moja ciekawość.

Ogólnie rzecz biorąc, jeśli w głownej formie tj. Notepad chcesz otworzyć plik i umieścić go w TextBox'ie to nie potrzebujesz do tego dodatkowej formy pokroju 'Open' - takie zadanie spełnia już gotowy OpenDialog, który zwraca Ci ścieżkę do pliku, który chcesz otworzyć. Tę ścieżkę należy przekazać np. do StreamReadera (https://docs.microsoft.com/pl-pl/dotnet/api/system.io.streamreader?view=netframework-4.8) i za jego pomocą zapisać treść pliku do TextBox'a. Rozumiem, że utworzenie dodatkowej formy "Open" wynika ze specyfiki zadania, jednak w pracy codziennej jest to zbędne.

w Twoim przypadku można dodać do formy Notepad publiczną funkcje która uzupełnia TextBox podanym tekstem i wywołać ją z poziomu formy "Open", wymaga to jednak aby forma "Open" posiadałą referencję do "Notepad" - możesz ją przekazać w konstruktorze - przeciąż go: zamiast
public Open(string path)
możesz zrobić
public Open(Form parent)
i potem np. jak zczytasz tekst ze StreamReadera do powiedzmy zmiennej fileContent to:
parent.FillTextBox(fileContent); <--- coś w tym stylu
Druga opcja to można wykorzystać delegaty, ale to droga na około.

Pozdrawiam.

komentarz 7 czerwca 2019 przez MakaBresk Obywatel (1,060 p.)
edycja 7 czerwca 2019 przez MakaBresk

Nie doszedłem do rozwiązania poprzedniego problemu - przekazanie parametru poprzez konstruktor. 

 

Treść zadania wygląda tak: Napisz program, który wczyta plik tekstowy – wyświetli go. Pozwoli na jego edycję oraz ponowny zapis pliku.(Prosty program notatnik)

 

Kod poprawiłem, usunąłem 2 dodatkowe formularze i zostawiłem tylko 1 o nazwie Notepad.cs
Kod:

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 Zadanie_11
{
    // Ikony dla menu pobrane z www.flaticon.com

    public partial class Notepad : Form
    {
        public Notepad()
        {
            InitializeComponent();
        }

        private void OtwórzToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            if (openFileDialog.ShowDialog() == DialogResult.OK) // Sprawdzenie czy w dialogu został wciśnięty przycisk OK
            {
                try
                {
                    string path_to_file = openFileDialog.FileName; // Wprowadzenie ścieżki do pliku do zmiennej path

                    string[] lines = System.IO.File.ReadAllLines(path_to_file); // Wczytanie zawartości wybranego pliku

                    // Wyświetlenie zawartości pliku w kontrolce richTextBox
                    for (int i = 0; i < lines.Length; i++)
                        richTextBox1.Text += lines[i] +Environment.NewLine;
                    // Environment.NewLine - przejście do nowej linii w richTextBox

                }
                catch (Exception ex) // Obsługa wyjątku błąd przy otwarciu pliku
                {
                    MessageBox.Show("Błąd wyboru pliku: " + ex.Message);
                }
            } 
        }

        private void ZapiszToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            if (saveFileDialog.ShowDialog() == DialogResult.OK) // Sprawdzenie czy w dialogu został wciśnięty przycisk OK
            {
                try
                {
                    string path_to_file = saveFileDialog.FileName; // Wprowadzenie ścieżki do pliku do zmiennej path
                    string content = richTextBox1.Text; // Wprowadzenie do zmiennej tekstu z kontroli richTextBox

                   System.IO.File.WriteAllText(path_to_file, content); // Zapisanie wprowadzonych zmian do pliku
                }
                catch (Exception ex) // Obsługa wyjątku błąd przy otwarciu pliku
                {
                    MessageBox.Show("Błąd wyboru pliku " +ex.Message);
                }
            }
        }

        private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close(); // Zamykanie formularza
        }
    }
}

 

edit: A tutaj wygląd samego programu:

komentarz 8 czerwca 2019 przez DarthMazut Bywalec (2,990 p.)

Tak, teraz wygląda to lepiej :)

Ciekawi mnie jednak dlaczego przy odczytywaniu pliku używasz metody ReadAllLines, która zwraca tablicę stringów wymagającą późniejszej iteracji zamiast ReadAllText, która zwraca cały tekst w postaci jednego stringa - analogicznie jak przy zapisie ;)

Jeśli chodzi o obsługę wyjątków to w blok try {} wystarczy wziąć metody Read* i Write*, nie widzę jak pozostałe linie mogłyby wygenerować wyjątek...  (oczywiście kolejność operacji zachowaj - wiem, że to oczywiste ale mówię na wszelki wypadek).

Poza tym myślę, że jest OK. Rozumiem, że kod działa? Ja niestety teraz nie mam dostępu do IDE więc nie sprawdzę cool

komentarz 8 czerwca 2019 przez MakaBresk Obywatel (1,060 p.)

Dzięki za wskazówki, nie pomyślałem o tym, że niepotrzebnie tworzę pętlę, która będzie iteracyjnie wyświetlać zawartość z pliku. 

Poprawiłem to, usunąłem kilka niepotrzebnych zmiennych i kod teraz wygląda następująco: 

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 Zadanie_11
{
    // Ikony dla menu pobrane z www.flaticon.com

    public partial class Notepad : Form
    {
        public Notepad()
        {
            InitializeComponent();
        }

        private void OtwórzToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            if (openFileDialog.ShowDialog() == DialogResult.OK) // Sprawdzenie czy w dialogu został wciśnięty przycisk OK
            {
                string path_to_file = openFileDialog.FileName; // Wprowadzenie ścieżki do pliku do zmiennej path

                try
                {
                    richTextBox1.Text = System.IO.File.ReadAllText(path_to_file); // Wyświetlenie zawartości pliku w kontrolce richTextBox
                }
                catch (Exception ex) // Obsługa wyjątku błąd przy otwarciu pliku
                {
                    MessageBox.Show("Błąd wyboru pliku: " + ex.Message);
                }
            } 
        }

        private void ZapiszToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            if (saveFileDialog.ShowDialog() == DialogResult.OK) // Sprawdzenie czy w dialogu został wciśnięty przycisk OK
            {
                string path_to_file = saveFileDialog.FileName; // Wprowadzenie ścieżki do pliku do zmiennej path

                try
                {
                    System.IO.File.WriteAllText(path_to_file, richTextBox1.Text); // Zapisanie treści z kontroli richTextBox do pliku
                }
                catch (Exception ex) // Obsługa wyjątku błąd przy otwarciu pliku
                {
                    MessageBox.Show("Błąd wyboru pliku " +ex.Message);
                }
            }
        }

        private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close(); // Zamykanie formularza
        }
    }
}

Oczywiście wszystko działa jak należy, nie zostają wyświetlone żadne błędy.

Wielkie dzięki za pomoc.

 

komentarz 8 czerwca 2019 przez DarthMazut Bywalec (2,990 p.)

Wygląda w porządku yes

Podobne pytania

0 głosów
1 odpowiedź 479 wizyt
0 głosów
1 odpowiedź 352 wizyt
+1 głos
2 odpowiedzi 132 wizyt
pytanie zadane 8 lipca 2023 w C# przez xFrikeQ Nowicjusz (130 p.)

92,573 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...