Przekazywanie listy między formularzami

0

Powoli zaczynam się wdrażać do pisania w C#, ale napotkałem problem. Byłem w lokalnym Empiku ale nie znalazłem odpowiadającej mi książki, więc bazuję na tym, co przeczytam w Internecie, dlatego również pytam się tutaj.
Najpierw ogólnie: Po otwarciu głównego okna program wczytuje na listę obiektów typu "film" dane z pliku tekstowego (to działa). Potem chcę przekazać tę listę do innego okna/formularza (co nie działa), który ma prezentować dane z tej listy, . Wygląda to tak:

W klasie Program stwiorzyłem klasę film.

 public partial class film
        {
            public int Lp;
            public string tytul;
            public string rezyser;
            public int rok;
            public string gatunek;
            public int ocena;
            public string ktoma;
        } 

W głównym oknie aplikacji (formularz Katalog) zadeklarowałem listę obiektów typu film - ta lista nazywa się "filmy". Dalej jest otwieranie kolejnego formularza typu TabelaFilm

   public partial class Katalog : Form
    {
        List<Program.film> filmy;  
        
        public Katalog()
        {
           
             InitializeComponent();

             (...)

             private void listaPlytToolDane_Click(object sender, EventArgs e)
            {
                TabelaFilm Tab = new TabelaFilm(this);
                Tab.Owner = this;
                Tab.ShowDialog();
            }
        }
    }  

Klasa TabelaFilm wygląda tak:

 namespace WindowsFormsApplication1
{
    public partial class TabelaFilm : Form
    {
        Katalog katalog;
        public TabelaFilm(Katalog katalog)
        {
            InitializeComponent();
            this.katalog = katalog; 
            
            TabelaFilmy.DataSource = katalog.filmy;
        }                       
    }
}

I właśnie w ostatniej linijce cytowanego kodu dostaję błąd " 'WindowsFormsApplication1.Katalog.filmy' is inaccessible due to its protection level". O ile rozumiem, lista "filmy" nie jest publiczna i dlatego nie mogę jej użyć w "obcym" obiekcie typu TabelaFilm. Co powinienem zmienić? Z góry dziękuję. :)

0
rektor napisał(a)

W klasie Program stwiorzyłem klasę film.

 public partial class film
        {
            public int Lp;
            public string tytul;
            public string rezyser;
            public int rok;
            public string gatunek;
            public int ocena;
            public string ktoma;
        } 

W jakim celu zagnieździłeś tę klasę?
Dlaczego nadałeś jej modyfikator partial?
Dlaczego jej nazwa jest z małej litery?
Dlaczego użyłeś pól zamiast właściwości?
Dlaczego ich nazwy zaczynają się małymi literami?

TabelaFilm Tab = new TabelaFilm(this);

Dlaczego nazwa zmiennej lokalnej zaczyna się wielką literą?

O ile rozumiem, lista "filmy" nie jest publiczna i dlatego nie mogę jej użyć w "obcym" obiekcie typu TabelaFilm. Co powinienem zmienić? Z góry dziękuję. :)

Dobrze rozumiesz, za to ja nie rozumiem, czemu skoro wiesz co jest źle, nie zrobisz tego?
Zmień po prostu jej modyfikator dostępu na public.

0

Na poczatku przepraszam za brak polskich znakow.

Troche chyba niektorych wkurzam moimi bledami. Widze. ze zrobilem ich wiele, ale to poczatek, to wlasciwie moja pierwsza proba napisania aplikacji w tym jezyku. Po pytaniach z poprzedniego posta nanioslem troche poprawek, ale problem nie jest rozwiazany. Tworze liste obiektow typu "Film" w podstawowym oknie programu, wszystko dobrze sie dodaje na te liste, ale gdy otwieram nowe okno to nie udaje mi sie do niego przekazac tej listy. Ta struktura jest wtedy rowna null, co zapewne oznacza, ze instancja tej listy przestala istniec. Ustawilem modyfikator dostepu na "public". Nie wiem, co zrobic, zeby ta lista byla dostepna dla drugiego okna - probowalem na rozne sposoby, ale nie udalo sie na razie.

0

Pole obiektu samo sobie tak nie znika. Pokaż jak wypełniasz tą kolekcję

0
rektor napisał(a)

Troche chyba niektorych wkurzam moimi bledami.

Ech te marzenia...

Tworze liste obiektow typu "Film" w podstawowym oknie programu, wszystko dobrze sie dodaje na te liste, ale gdy otwieram nowe okno to nie udaje mi sie do niego przekazac tej listy. Ta struktura jest wtedy rowna null, co zapewne oznacza, ze instancja tej listy przestala istniec. Ustawilem modyfikator dostepu na "public". Nie wiem, co zrobic, zeby ta lista byla dostepna dla drugiego okna - probowalem na rozne sposoby, ale nie udalo sie na razie.

Z opisu wynika, że robisz to poprawnie i powinno działać. Jeśli tak nie jest, to problem jest w kodzie, którego nie pokazałeś.

0

OK, jakoś udało mi się to rozwiązać, ale ciągle mam przeczucie, że nie jest to najlepszy sposób. Teraz to wygląda tak, że w klasie głównego okna (Katalog) zrobiłem metodę TxtNaList(), która dodaje obiekty na listę i tę listę zwraca.

 public List<Film> TxtNaList()
        {
            listafilmow = new List<Film>();

            FileStream fs = new FileStream("D:/plyty/plyty.txt", FileMode.Open);
            StreamReader sr = new StreamReader(fs);          //Wykorzystanie klasy do prostego czytania tekstu

            string[] dane = new string[6];

            while (sr.EndOfStream == false)          //Wykonuj dopoki odczyt nie dojdzie do konca pliku
            {

                string linia = sr.ReadLine();
                if (!string.IsNullOrEmpty(linia))
                {
                    dane = linia.Split(';');                  //Rozbij string na tablice stringow przy pomocy separatora ';'
                    Film film = new Film();

                    film.Lp = listafilmow.Count + 1;
                    film.tytul = dane[0];
                    film.rezyser = dane[1];
                    film.rok = int.Parse(dane[2]);
                    film.gatunek = dane[3];
                    film.ocena = int.Parse(dane[4]);
                    film.ktoma = dane[5];
                    
                    if (!listafilmow.Contains(film))
                    {
                        listafilmow.Add(film);
                    }
                }      
            }
            return listafilmow;
        }

Otwieranie nowego formularza:

private void listaPlytToolDane_Click(object sender, EventArgs e)
        {
            TabelaFilm tab = new TabelaFilm();
            tab.katalog = this;
            tab.ShowDialog();
        }

I w nowym oknie odwołuję się do metody TxtNaList().

 public partial class TabelaFilm : Form
    {
        public Katalog katalog;
        public TabelaFilm()
        {
            InitializeComponent();
        }

        private void TabelaFilm_Load(object sender, EventArgs e)
        {
            this.tabelaFilmy.DataSource = ((Katalog)katalog).TxtNaList();
        }
                               
    } 

Robilibyście to tak samo, czy inaczej? W pierwotnym założeniu myślałem raczej w ten sposób, żeby dodawać na liste po załadowaniu głównego okna, a potem tylko przekazać pełną strukturę do drugiego, a nie dodawać na listę dopiero w drugim oknie.

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