Zmienna globalna? C#

public partial class Form1 : Form

    {

        private int currentIndex;

        private List images;


        public Form1()

        {

            InitializeComponent();

        }


        private void Form1_Load(object sender, EventArgs e)

        {

            currentIndex = 0;

            images = GetImages();

        }


        private void button1_Click(object sender, EventArgs e)

        {

            currentIndex = 0;

            pictureBox1.Image = images[currentIndex];

        }


        private void button4_Click(object sender, EventArgs e)

        {

            currentIndex = images.Count - 1;

            pictureBox1.Image = images[currentIndex];

        }


        private void button3_Click(object sender, EventArgs e)

        {

            if (currentIndex != 0)

                currentIndex--;

            pictureBox1.Image = images[currentIndex];

        }


        private void button2_Click(object sender, EventArgs e)

        {

            if (currentIndex != (images.Count - 1))

                currentIndex++;

            pictureBox1.Image = images[currentIndex];

        }


        private List GetImages()

        {

            HashSet imagesExtensions = new HashSet() { "png", "jpg" };

            string directoryPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "pct");


            return GetImages(directoryPath, imagesExtensions);

        }


        private List GetImages(string directoryPath, HashSet imagesExtensions)

        {

            List result = new List();

            string[] fileNames = Directory.GetFiles(directoryPath);

            foreach (string fileName in fileNames)

                if (imagesExtensions.Contains(Path.GetExtension(fileName).Replace(".", "")))

                    result.Add((Image)(new Bitmap(fileName)));

            return result;

        }

    }

Następnym razem jak coś Ci nie będzie działać to pisz dokładnie co nie działa i czy pojawia się jakiś komunikat błędu. Moja magiczna kula aktualnie leży w piwnicy. Jedyny błąd jaki zauważyłem w kodzie to próba pobrania elementu listy o indeksie równym ilości elementów tej listy. Elementy listy numerowane są od 0, a więc ostatni element listy ma indeks równy list.Count - 1. Wprowadziłem jeszcze oprócz tego drobne poprawki do metod obsługujących zdarzenie Click poszczególnych przycisków. Teraz powinno działać.

Dzięki za pomoc, ale dalej nie działa :cry:

Index out of range…

W tym miejscu:

string[] fileNames = Directory.GetFiles(directoryPath);

Dziwne, że ten błąd został wyrzucony w tej linijce. Anyway najprawdopodobniej chodzi o to, że w folderze, który kryje się pod ścieżką directoryPath nie ma żadnego zdjęcia o rozszerzeniu png lub jpg. Wprowadziłem drobne poprawki w kodzie, żeby ten wyjątek się już nie pojawił:

public partial class Form1 : Form

    {

        private int currentIndex;

        private List images;


        public Form1()

        {

            InitializeComponent();

        }


        private void Form1_Load(object sender, EventArgs e)

        {

            images = GetImages();

            button1_Click(null, null);

        }


        private void button1_Click(object sender, EventArgs e)

        {

            if (images != null && images.Count > 0)

            {

                currentIndex = 0;

                pictureBox1.Image = images[currentIndex];

            }

        }


        private void button4_Click(object sender, EventArgs e)

        {

            if (images != null && images.Count > 0)

            {

                currentIndex = images.Count - 1;

                pictureBox1.Image = images[currentIndex];

            }

        }


        private void button3_Click(object sender, EventArgs e)

        {

            if (images != null && images.Count > 0)

            {

                if (currentIndex != 0)

                    currentIndex--;

                pictureBox1.Image = images[currentIndex];

            }

        }


        private void button2_Click(object sender, EventArgs e)

        {

            if (images != null && images.Count > 0)

            {

                if (currentIndex != (images.Count - 1))

                    currentIndex++;

                pictureBox1.Image = images[currentIndex];

            }

        }


        private List GetImages()

        {

            HashSet imagesExtensions = new HashSet() { "png", "jpg" };

            string directoryPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "pct");


            return GetImages(directoryPath, imagesExtensions);

        }


        private List GetImages(string directoryPath, HashSet imagesExtensions)

        {

            List result = new List();

            string[] fileNames = Directory.Exists(directoryPath) ? Directory.GetFiles(directoryPath) : null;

            if (fileNames != null && fileNames.Length > 0)

                foreach (string fileName in fileNames)

                    if (imagesExtensions.Contains(Path.GetExtension(fileName).Replace(".", "")))

                        result.Add((Image)(new Bitmap(fileName)));

            return result;

        }

    }

BTW Jeśli Ty ten kod odpalasz na linuxie przy użyciu Mono to musisz sprawdzić co kryje się w zmiennej directoryPath, bo nie wiem, czy te metody Path.Combine itd. poprawnie działają w Mono.

Jest spoko, ale dalej żadne zdjęcie się nie wczytuje :-o Chmmm. Może folder inaczej umiejscowić ?

  1. Nie odpowiedziałeś mi na pytanie. Czy Ty ten kod odpalasz na linuxie czy Windowsie (czy może jeszcze czymś innym)?

  2. Czy sprawdziłeś zmienną directoryPath w debuggerze (w sensie, czy zawiera ścieżkę do folderu ze zdjęciami)?

  3. Jeśli to Windows Vista/7 to spróbuj uruchomić program jako administrator i zobacz, czy wtedy wyświetlą się zdjęcia.

Ok. Przepraszam.

  1. Winows 7

2.“D:\Programowanie\Projekty\Wanderung Wędrówka Putovani\Wanderung Wędrówka Putovani\bin\Debug\pct” oddaje ( może jakby dodać / ?)

  1. Uruchamiam jako Admin

Ustaw breakpoint na tej linijce

if (fileNames != null && fileNames.Length > 0)

i zobacz, czy fileNames zawiera listę plików z tego katalogu pct.

[0] “D:\Programowanie\Projekty\Wanderung Wędrówka Putovani\Wanderung Wędrówka Putovani\bin\Debug\pct\P1010004.JPG” string

[1] “D:\Programowanie\Projekty\Wanderung Wędrówka Putovani\Wanderung Wędrówka Putovani\bin\Debug\pct\P1010005.JPG” string

[2] “D:\Programowanie\Projekty\Wanderung Wędrówka Putovani\Wanderung Wędrówka Putovani\bin\Debug\pct\P1010006.JPG” string

No to nie wiem co jest grane. Jeszcze możesz ustawić breakpoint na tej linijce

button1_Click(null, null);

i zobaczyć, czy kolekcja images jest wypełniona, choć nie widzę powodów, dla których nie miałaby być wypełniona.

  • this {Wanderung_Wędrówka_Putovani.Form1, Text: Wanderung Wędrówka Putovani} Wanderung_Wędrówka_Putovani.Form1

sender null object

  • e null System.EventArgs

Miałeś mi powiedzieć, czy kolekcja obrazków (zmienna images) jest pusta, czy nie jest pusta. Nie interesuje mnie jakie argumenty są przesłane do procedury, bo przecież je znam.

Przepraszam błąd.

to to:

  • images Count = 0 System.Collections.Generic.List

Nic się nie stało. Dobra to w końcu do czegoś doszliśmy. Zamień tą linijkę:

if (imagesExtensions.Contains(Path.GetExtension(fileName).Replace(".", "")))

na tą

if (imagesExtensions.Contains(Path.GetExtension(fileName).ToLower().Replace(".", "")))

i zobacz, czy zacznie działać (powinno już teraz być wszystko OK).

Dzięki. Nie wiem, który raz mi już pomogłeś matzu :smiley: Wszystko działa.

Dodane 25.05.2011 (Śr) 21:04

Chmmm. Zacząłem do tego pisać pokaz slajdów w backgroundworkerze, ale wywala błąd:

Cross-thread operation not valid: Control 'button1' accessed from a thread other than the thread it was created on.

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)

        {

            while (radioButton1.Checked == true)

            {






                button1.Enabled = false;

                button2.Enabled = false;

                button3.Enabled = false;

                button4.Enabled = false;


                Thread.Sleep(Convert.ToInt32(toolStripTextBox1.Text) * 100);


                if (images != null && images.Count > 0)

                {

                    if (currentIndex < (images.Count - 1))

                        currentIndex++;




                    pictureBox1.Image = images[currentIndex];



                }

                else

                {

                    MessageBox.Show("Koniec");

                    radioButton2.Select();



                    button1.Enabled = true;

                    button2.Enabled = true;

                    button3.Enabled = true;

                    button4.Enabled = true;


                    this.backgroundWorker1.CancelAsync();


                    break;

                }


                MessageBox.Show("Koniec");

            }

W procedurze obsługującej zdarzenie DoWork nie można modyfikować właściwości kontrolek formularza (stąd ten wyjątek). Co najwyżej możesz odczytywać ich wartość (choć tego też tak na prawdę nie powinno się robić). Jeśli chcesz dokonać modyfikacji formularza w trakcie pracy backgroundworker-a to musisz to zrobić w procedurze obsługującej zdarzenie ProgressChanged (ewentualnie jeszcze przed wywołaniem metody RunWorkerAsync.

Dzięki. To już działa. Aleeee…

Podczas debugowanie wywala:

Out of memory.

Dodałem więcej zdjęć do folderu. Co robić ?

Im dalej w las, tym więcej drzew :). Komunikat błędu jest dość jasny. Zabrakło RAM-u. Jeśli masz system 32bit-owy to program może maksymalnie zaadresować 2GB RAM-u. Zgaduję, że wrzuciłeś tyle zdjęć do tego folderu, że program się wyłożył (mi to często zdarzało się w starszej wersji firefoxa, gdy ściągałem przy jego użyciu duże pliki).

Trzeba będzie przerobić ten kod. Będziesz musiał zrezygnować z buforowania wszystkich zdjęć i wczytywać je pojedynczo. Mógłbyś też wczytywać je partiami, ale w sumie jak się zastanowić, to wczytywanie pojedynczo będzie lepsze. Załóżmy, że użytkownik w trakcie działania programu usunie zdjęcie z dysku. W programie w buforze wciąż byłoby przechowywane i zostałoby wyświetlone mimo tego, że na dysku już go nie ma. Zresztą załóżmy, że użytkownik w trakcie działania programu wrzuci zdjęcie do folderu, którego zawartość jest aktualnie wyświetlana. Z racji tego, że korzystasz z bufora to to zdjęcie nie zostałoby wyświetlone, bo bufor nie jest nigdzie odświeżany.

Pokombinuj na razie sam jak to przerobić, żeby to miało ręce i nogi. Jak nic nie wykombinujesz to postaram się podrzucić Ci jakiś pomysł. Tylko jak będziesz nad tym myślał to postaraj się tak to zrobić, aby jak najwięcej kodu przenieść do osobnych klas. Możesz sobie np. zrobić klasę MyImage, która będzie miała pola Bitmap i FilePath oraz metody Exists oraz Read. Oraz klasę MyImages, która będzie miała metody GetPrevious, GetNext, GetFirst, GetLast. Coś w ten deseń.

Niedobrze. To na jutro musi być gotowe :expressionless:

Użytkownik nie będzie mógł usunąć zdjęcia, bo ono będzie na cd.

To jest jeszcze masa czasu, bo to nie jest nic trudnego. W zasadzie wszystkie informacje już masz, żeby sobie z tym poradzić. Możesz mi podrzucić kod całego projektu (spakowany) na priva. Usiądę teraz przy tym i coś tam porobię. Mam godzinę czasu, bo potem spadam na film (ewentualnie jeszcze po filmie z 1,5h będę) :stuck_out_tongue:

Chmmm. Podzieliłem to na dwa foldery.

dvd i dvd2

I teraz trzeba to wstukać do kody, żeby po obejrzeniu wszystkich z dvd przechodził do dvd2 i brał resztę…