Autor Wątek: problem z tablicą  (Przeczytany 5830 razy)

Offline larden

  • Użytkownik

# Październik 25, 2007, 21:48:12
Witam!
  Mam problem. Nie wiem w jaki sposób odpytać w zdarzeniu, który obrazek został kliknięty. I mam pytanie. Czy dobrze zrobiłem że wszystkie PictureBox'y przypisane są jednemu delegatowi?
Kod: (csharp) [Zaznacz]
public partial class Form1 : Form
    {
        public PictureBox[] pole = new PictureBox[100];

        public Form1()
        {
            InitializeComponent();
            Rysuj();
        }

        public void Rysuj()
        {
            for (int i = 0; i < 100; i++)
            {
                pole[i] = new PictureBox();
                mypanel.Controls.Add(pole[i]);
                pole[i].Location = new System.Drawing.Point(40 * (i % 10), 40 * (i / 10));
                pole[i].Name = "Pole" + i.ToString();
                pole[i].Size = new Size(40, 40);
                pole[i].BackgroundImage = Bitmap.FromFile("morze.png");
                pole[i].BackgroundImageLayout = ImageLayout.Stretch;
                pole[i].Tag = i.ToString();
                pole[i].BorderStyle = BorderStyle.FixedSingle;
                pole[i].Click += new EventHandler(this.pole_Click);
            }
        }
        private void pole_Click(object sender, EventArgs e)
        {
            if ()
            {
               
            }
            else
            {
            }
        }

    }


Offline Mr. Spam

  • Miłośnik przetworów mięsnych

RageX

  • Gość
# Październik 26, 2007, 03:41:14
Patrz... wywołany zostaje handler przypisany danemu obrazkowi. A że wszystkim masz przypisany ten sam to zostaje wywołana jedna i ta sama metoda. Na podstawie tego nie da rady wywnioskować o co cho... Obuduj ten twój guzik w jeszcze jakąś klasę i przyporzadkuj każdemu guzikowi, swój handler. W zasadzie dało by się odzyskać ten twój obiekt z sendera chyba... nie widziałem aby ktoś używał, sam czegoś takiego nie robiłem, odradzam tobie. :)

Offline larden

  • Użytkownik

# Październik 26, 2007, 09:56:20
Ale gdy "obudowuje mój guzik w klasę" to mam problem z dodaniem go do Panelu. Po prostu nie mam dostępu na ten obiekt, który jest utworzony w Form1.
Kod: (csharp) [Zaznacz]
mypanel.Controls.Add(pole[i]);

Offline Xion

  • Moderator
    • xion.log

# Październik 26, 2007, 10:25:07
Oczywiście się da wywnioskować. Parametr sender, który dostajesz w zdarzeniu, to referencja do obiektu, którego zdarzenie dotyczy. Sprawdź więc, któremu PictureBoksowi jest ona równa.
Jeśli jednak zechcesz obudować tą kontrolkę w klasę, to wszystkie jej parametry będziesz musiał ustawić ręcznie w kodzie. Najlepiej stwórz ja wizualnie i skopiuj kod Designera.

Offline larden

  • Użytkownik

# Październik 26, 2007, 11:50:03
Czyli mam w Desinerze utworzyć 100 takich kontrolek, tak..? i sterować nimi z innej klasy?

RageX

  • Gość
# Październik 26, 2007, 12:27:04
Oczywiście się da wywnioskować. Parametr sender, który dostajesz w zdarzeniu, to referencja do obiektu, którego zdarzenie dotyczy. Sprawdź więc, któremu PictureBoksowi jest ona równa.
Jeśli jednak zechcesz obudować tą kontrolkę w klasę, to wszystkie jej parametry będziesz musiał ustawić ręcznie w kodzie. Najlepiej stwórz ja wizualnie i skopiuj kod Designera.
Przecież w drugiej części to nakreśliłem... musiałeś mi wbijać?  ::)  :D

Offline Xion

  • Moderator
    • xion.log

# Październik 26, 2007, 12:30:19
Oczywiście się da wywnioskować. Parametr sender, który dostajesz w zdarzeniu, to referencja do obiektu, którego zdarzenie dotyczy. Sprawdź więc, któremu PictureBoksowi jest ona równa.
Jeśli jednak zechcesz obudować tą kontrolkę w klasę, to wszystkie jej parametry będziesz musiał ustawić ręcznie w kodzie. Najlepiej stwórz ja wizualnie i skopiuj kod Designera.
Przecież w drugiej części to nakreśliłem... musiałeś mi wbijać?  ::)  :D
Nakreśliłeś z dużą dozą niepewności i generalnie odradzałeś - ja polecam, więc jest jakaś różnica :)

Offline larden

  • Użytkownik

# Październik 26, 2007, 12:56:07
zgłupiałem ... ???  Wiem, że z obiektu sender muszę wszystko wyciągnąć za pomocą GetType(), ale czy da się sprawdzić przez ten obiekt jaki bacground-image posiada PictureBox w który kliknąłem ..:P

RageX

  • Gość
# Październik 26, 2007, 13:03:55
Nie... ponieważ nie masz identyfikatorów do obrazków, natomiast możesz nazwę guzika porównać.
GetType() zwraca ci typ... a ty typ znasz. Nie próbowałem, ale ja bym zcastował do tego typu i sprawdził po polach, proste? A czy możliwe?
Xion: prawda... nie próbowałem, nie widziałem. Wolałbym przypisać oddzielne handlery. :)

Offline Limal

  • Użytkownik
    • http://wolnik.co.uk

# Październik 26, 2007, 13:53:45
larden, Twój "problem" jest jednym z najczęściej spotykanych, dlatego twórcy C# postarali się by był on jak najprostszy do rozwiązania.

Zobacz, jak wspominali już Xion i RageX, każdy PictureBox wywołuję metodę Click, jak tylko zostanie przyciśnięty, a jako argument podaje referencję do swojej instancji. Stąd już prosta droga do stwierdzenia jakie tło ma dany PictureBox.

Ujmując słowa w kod:

Kod: (csharp) [Zaznacz]
private void pole_Click(object sender, EventArgs e)
{
PictureBox pictureBox = (PictureBox)sender;

MessageBox.Show(pictureBox.Name); // tutaj wyswietli sie nazwa wcisnietego pola
}

Offline larden

  • Użytkownik

# Październik 26, 2007, 14:17:42
Dzięki chłopaki rozjaśniliście człowiekowi głowę.. ;)  Limal właśnie o to mi chodziło :)

Offline Esidar

  • Użytkownik

# Październik 26, 2007, 21:36:11
Kod który wrzuciłeś jest dobry. Tak możesz właśnie robić.

Co do przypisywania do zmiennej "Tag". Nie musisz rzutować na string "i.ToString()". Wystarczy:
pole[i].Tag = i;

Potem wystarczy:
PictureBox pictureBox = (PictureBox)sender;
int i = (int)pictureBox.Tag;

Polecam też odzwyczaić się od rzutowania typowego dla C++ czyli
PictureBox pictureBox = (PictureBox)sender;

i zamiast tego używać
PictureBox pictureBox = sender as PictureBox;
if( pictureBox == null )
    return;

Można uniknąć dzięki temu różnych niespodzianek.

Offline Frondeus

  • Użytkownik

# Lipiec 06, 2008, 11:29:11
Dopisze się do tego tematu żeby nie tworzyć nowego.
Mam mały problem.
Stworzyłem tablicę obiektów klasy A;
I przy tworzeniu ich muszę wprowadzić dane do konstruktora.
pObjekt = new CKlasa[10](35);
Tak próbowałem ten problem rozwiązać, ale kompilator wyskakiwał z błędami.

 Jak to zrobić?



Offline revo

  • Użytkownik

# Lipiec 06, 2008, 12:23:52
Stworzyłem tablicę obiektów klasy A;
I przy tworzeniu ich muszę wprowadzić dane do konstruktora.
pObjekt = new CKlasa[10](35);
Tak próbowałem ten problem rozwiązać, ale kompilator wyskakiwał z błędami.

 Jak to zrobić?

Tworzenie tablicy w C# tworzy tablicę wypełnioną nullami (dla klas), dlatego trzeba napisać:

pObjekt = new CKlasa[10];
for (int i=0; i<10; i++) pObjekt[i] = CKlasa(35);

Offline Frondeus

  • Użytkownik

# Lipiec 06, 2008, 13:12:07
Mam jeszcze jedno pytanie:
Jak połączyć kilka tablic?(np. funkcja) tzn.
Mam tablice n-wymiarowe A, B i C.
I chce aby w C od np. 0 - 10 znalazły się dane tablicy A a od 11 do 20 dane z tablicy B...
Czy jest jakaś funkcja łącząca tablice( tak jak istnieją funkcje łączące  "stringi" ;) )?
Z góry dzięki za odp.

EDIT::
Kurde, wszędzie powstawiałem średniki zamiast kropek :D
« Ostatnia zmiana: Lipiec 07, 2008, 11:21:07 wysłana przez Frondeus »