Zmienna globalna? C#


(Jarek P) #1

Witam. Bardzo się spieszę i mam pewien problem. A mianowicie:

Pisze galerię zdjęć, w zasadzie na wczoraj. (w C#)

I mam problem z funkcją następne zdjęcie,

Zrobiłem listę zdjęć,

Ale kiedy mam coś takiego:

int x = 0;

            List lista = new List();

            lista.Add(_1.Properties.Resources.PICT0001);

            lista.Add(_1.Properties.Resources.PICT0002);

            pictureBox1.Image = lista[1];

            x++;

To po każdym kliknięciu zmienna x deklaruje się jako 0.

Jak rozwiązać ten problem ?

Chodzi mi o taką "globalną" zmienną.


(Blapiter) #2

Nie wiem jak masz tam zdefiniowane klasy, ale generalnie musiałbyś zdefiniować zmienną typu static, czyli taką która "pamięta".

public static int=0;

-- Dodane 23.05.2011 (Pn) 20:15 --

zmienna statyczna jest zmienna :stuck_out_tongue: tyle że tak niefortunnie nazywa się po polsku, generalnie jest to zmienna pamiętająca wartości dostępna nawet gdy nie została utworzona instancja klasy :slight_smile: "const" jest całkowicie nietykalna :wink:


(Jarek P) #3

Dzięki. O to mi chodziło. I przepraszam za moja pomyłkę. A propos, właśnie rozwiązałeś 90 % moich problemów :smiley:

-- Dodane 23.05.2011 (Pn) 20:34 --

Ok. Ale mam jeszcze jeden problem. A mianowicie mam w resources kilkaset zdjęć. Nie chciałbym wpisywać ich nazw po kolei do listy. Macie jakieś pomysły, może foreach ?


(Fiołek) #4

Resources nie są od trzymania kilkuset zdjęć. Jedno, dwa - tak, ale nie kilkaset. Zrób to w sensowny sposób i ładuj je w trakcie działania programu(np. wszystkie zdjęcia z danego folderu).

W ostateczności: w zasobach zrób tablicę zdjęć, a jeśli "tak się nie da"(nie sprawdzałem) zrób foreach po wszystkich właściwościach, których nazwa spełnia dany warunek, tzn.:

//Kod pisany z palca, błędy są bardzo możliwe

Lista imgs = new Lista();

var pictProps = from p in _1.Properties.Resources.GetType().GetProperties() where p.Name.StartsWith("PICT") select p; //Wybieramy tylko te, których nazwa zaczyna się od "PICT"

foreach(var prop in pictProps)

{

imgs.Add(prop.GetValue(_1.Properties.Resources, null) as Image);

}

(Jarek P) #5

W tym problem, że one się różnie nazywają :frowning: A jest ich tyle, że do soboty nie zdążę ich nazwać. To musi być jakaś pętla, która wczytuje wszystkie pliki z resources,


(Fiołek) #6

Skonstruuj odpowiedni warunek, albo zrób to tak, jak być powinno - NIE TRZYMAJ TYLU ZDJĘĆ W ZASOBACH!


(Jarek P) #7

Ok. Powiedzmy, że odpuszczam zasoby. Gdzie najlepiej je trzymać ? Nie mówię o zwykłym folderze, bo to już ostateczność.


(Fiołek) #8

Zwykły folder. Co jest w nim takiego złego? Ew. Isolated Storage.


(Jarek P) #9

No dobra. Niech będzie folder. Jakoś to przeżyję . :slight_smile:

Ale zdjęć jest kilkaset. Wprowadzanie filestreamów by mnie wykończyło. Jakieś pomysły ?

PS. Mają różne nazwy.


(Tomek Matz) #10

Generalnie powinieneś zrobić tak jak napisał Fiołek. Resources służą do przechowywania tylko tego, co jest niezbędne do działania samego programu. Tak, czy siak wrzucam Ci kod, który możesz sobie sprawdzić.

List list = new List();

PropertyInfo[] infos = (new Properties.Resources()).GetType().GetProperties(BindingFlags.Static | BindingFlags.NonPublic);

foreach (PropertyInfo info in infos)

    if (info.PropertyType.Equals(typeof(Bitmap)))

        list.Add((Bitmap)Properties.Resources.ResourceManager.GetObject(info.Name));

Powinien Ci zwrócić kolekcję wszystkich Bitmap z Resources. Testowałem tylko pod kątem błędów kompilacji, więc nie wiem, czy do końca poprawnie to działa (ale raczej tak).

Jeśli chodzi o wczytywanie plików z folderu. Przyda Ci się metoda http://msdn.microsoft.com/en-us/library/07wt70x2.aspx. Użyjesz ją do wczytania nazw wszystkich plików z danego katalogu. Mając listę tych plików możesz skorzystać z metody http://msdn.microsoft.com/en-us/library/system.io.path.getextension.aspx, żeby odczytać rozszerzenie każdego z tych plików. Ostatnim krokiem jest utworzenie sobie bazy rozszerzeń plików graficznych (chyba możesz to wczytać z rejestru Windowsa, ale nie jestem pewien).


(Jarek P) #11

Dzięki. Na pewno się przyda.

-- Dodane 24.05.2011 (Wt) 20:39 --

Ok to jeszcze jedna rzecz. Całość ma być na cd. Jak uzyskać dostęp do folderu (ReadOnly) an dysku ? (Niektórzy maja różne nazwy dysku).


(Tomek Matz) #12

To nie ma znaczenia, czy będziesz odpalał z CD, pendrive, dysku zewnętrznego, czy czego tam jeszcze. Sposób odczytywania ścieżki folderu, w którym umieszczony jest exe jest taki sam:

string exeDirectoryPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

Później stosując sposoby znane z wiersza poleceń (np. exeDirectoryPath + "\Images") możesz sobie odczytać ścieżkę innego folderu.


(Jarek P) #13

Dzięki. Ale mam jeszcze jeden problem. A mianowicie:

Mam już listę zdjęć.

Ale nie bardzo wiem jak dodać do niej zdjęcia z pliku : (baza to elos)

private List Pobierz_Pliki(string sciezka)

        {


            string ex = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

            sciezka = ex + "/pct"; // nazwa folderu



            Directory.GetFiles(sciezka);

            List pliki = Directory.GetFiles(sciezka).ToList();

            return pliki;





            foreach (string xec in pliki)

            {

                StreamReader sr = new StreamReader(sciezka);

              //yyyyyyyy


            }



        }

(Fiołek) #14

Bitmap(String) albo Bitmap(Stream), jak wolisz.

Dodatkowo:

Podawanie absolutnych ścieżek jest zbędne - wystarczy, że "ścieżka" będzie równa "pct". Niech użytkownik decyduje czy chce uruchamiać w tym, czy innym folderze.

Zwracasz ścieżki do obrazków - nie lepiej je od razu ładować?


(Tomek Matz) #15

@Jarek P

Kod, który wkleiłeś to niezły chaos :). Poniżej masz poprawioną wersję. Musisz jeszcze zaimplementować obsługę wyjątków oraz pobieranie informacji o rozszerzeniach plików graficznych (tak jak mówiłem chyba można to wczytać z rejestru).

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;

}

Jeśli teraz musisz te obrazki zapisywać do bazy danych to poczytaj o BLOB-ach. Ja akurat teraz nie mogę znaleźć jakiegoś sensownego linku, żeby Ci podrzucić, ale jest tego sporo na necie, więc na pewno coś znajdziesz.


(Jarek P) #16

Chmmm. Powinno działać, ale wywala błąd...

Error	1	The name 'Assembly' does not exist in the current context	D:\Programowanie\Projekty\Wanderung Wędrówka Putovani\Wanderung Wędrówka Putovani\Form1.cs	45	71	Wanderung Wędrówka Putovani

(Tomek Matz) #17

Musisz dodać przestrzeń nazw

using System.Reflection;

Zresztą, żeby ten pierwszy fragment kodu działał (ten służący do iterowania po Resources), też niezbędne jest dodanie tej przestrzeni nazw.


(Jarek P) #18

Dzięki.

-- Dodane 25.05.2011 (Śr) 16:25 --

Chmmm.

Dopisałem coś takiego:

ele = result;


            return result;

Ale zwraca nulla...

Object reference not set to an instance of an object.

(Tomek Matz) #19

Nie rozumiem?


(Jarek P) #20

Znaczy, że jest nullem.

-- Dodane 25.05.2011 (Śr) 16:55 --

internal 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)));

                }

            }


            ele = result; // = null; Ps to już naprawiłem, zapomniałem wywołać metodę #-o  


            return result;




        }

Ale z tym mam problem;

private List GetImages()

        {

            MessageBox.Show("Ładowanie zdjęć");

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

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


            return GetImages(directoryPath, imagesExtensions);

        }

Żeby to uruchomić. -- Dodane 25.05.2011 (Śr) 16:58 -- Może ja podam cały kod:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.IO;

using System.Reflection;


namespace Wanderung_Wędrówka_Putovani

{

    public partial class Form1 : Form

    {


        public static int elos = 0;

        public static List ele;





        public Form1()

        {



            InitializeComponent();


        }




        private List GetImages()

        {

            MessageBox.Show("Ładowanie zdjęć");

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

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


            return GetImages(directoryPath, imagesExtensions);

        }


        internal 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)));

                }

            }


            ele = result;


            return result;




        }



        private void Form1_Load(object sender, EventArgs e)

        {



            Form1 pr = new Form1();


                      pr.????????????????????(???) ////////// Tu




        }


        ///








        /// 







        private void button1_Click(object sender, EventArgs e)

        {

            pictureBox1.Image = ele[0];


        }


        private void button4_Click(object sender, EventArgs e)

        {

            pictureBox1.Image = ele[ele.Count];

        }


        private void button3_Click(object sender, EventArgs e)

        {

            elos--;

            pictureBox1.Image = ele[elos];

        }


        private void button2_Click(object sender, EventArgs e)

        {

            elos++;

            pictureBox1.Image = ele[elos];

        }

    }

}