Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2011
    Messaggi
    24

    c# associare evento a picturebox generate a runtime

    salve a tutti,
    sto realizzando un gioco in c# simile a risiko. Ho un problema quando vado a gestire le immagini delle carte possedute da ciascun giocatore. In pratica le carte possedute da un giocatore variano continuamente durante lo svolgimento del gioco perciò le devo caricare a runtime. Fino qui nessun problema particolare, vi posto il codice (le immagini si trovao nella cartella resources):
    codice:
    /*creo una lista contenente i nomi delle imagini*/
    public List<string> myList = new List<string>();
    
    /*al click di un bottone aggiungo i nomi dalle immagini delle carte possedute da un giocatore,
     *creo le pictureBox e visualizzo le immagini */
    
    private void button1_Click(object sender, EventArgs e)
    {
        myList.Add("image1");
        myList.Add("image2");
    
        /*in questo esempio per farvi capire carico solo due immagini predefinite, nell'applicazione finale
         *i nomi verranno presi da una classe Giocatore che conterrà, tra l'altro, anche le carte 
         *possedute dal giocatore */
    
        /*creo le picture box necessarie e vi inserisco le immagini*/
    
        foreach(string s in myList)
        {
            PictureBox pb = new PictureBox();
            pb.Width = 120;
            pb.Height = 150;
            pb.SizeMode = PictureBoxSizeMode.StretchImage;
            Image img = Properties.Resources.ResourceManager.GetObject(s) as Image;
            pb.Image = img;
            flowLayoutPanel1.Controls.Add(pb);   //per mantenere le immagini allineate
        }
    }
    Fino a qui nessun problema, le pictureBox vengono create e le immagini visualizzate.
    Ora però, per dare ai giocatori la possibilità di giocare un tris di carte, dovrei fare in modo che le immagini visualizzate siano cliccabili, in pratica devo associare ad ogni pictureBox che viene creata l'evento Click.
    Ho provato svariate soluzioni trovate in rete ma nessua mi funziona, se c'è qualcuno che può darmi qualche consiglio su come potrei fare ve ne sarei grato.
    Grazie.

  2. #2
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    basta 'aggiungere' all'evento l'handler che gestisce lo gesticsce:

    codice:
        pb.Click += myPb_Click;
    myPb_click è la funzione che verrà eseguita allo scatenarsi dell'evento. Poichè l'evento è una delegate (una multicast delegate per l'esattezza) il metodo deve avere una firma precisa che corrisponde a quella della delegate.
    Generalmente la firma degli eventi contiene un riferimento all'oggetto che ha scatenato l'evento, una serie di informazioni relative all'evento stesso che sono contenute in un oggetto di tipo derivato da EventArgs e ritorna void.
    codice:
        void myPbClick(object sender, EventArgs e)
    il sender è sempre un object percio quando lo utilizzi devi fare il casting. Premesso che EventArgs (il tipo base) va sempre bene, è meglio di volta in volta controllare su msdn che tipo specifico di EventArgs devi usare per un determinato evento cosi da poter gestire l'evento stesso piu facilmente.

    Dall'operatore += si evince che si possono aggiungere piu handler al singolo evento i quali verranno eseguiti in ordine uno dopo l'altro. Con -= si cancella la sottoscrizione di uno specifico handler all'evento.

    In pratica nulla di nuovo rispetto a quanto gia fai per le pictureBox che inserisci da visual studio solo che l'assegnazione dell'handler la fai a mano.

  3. #3
    Utente di HTML.it
    Registrato dal
    May 2011
    Messaggi
    24
    Grazie mille rsdpzed, funziona perfettamente.
    Ora però sto impazzendo con un altro problema. Così facendo le immagini vengono visualizzate perfettamente e viene anche rilevato l'evento click. Però adesso dovrei anche recuperare la carta che il giocatore vuole giocare quando clicca su di essa. Avevo pensato di usare la proprietà tag per differenziare le varie carte, riporto un esempio:
    codice:
    private void button1_Click(object sender, EventArgs e)
    {
        for(int i = 0; i < myList.Count; i++)  //myList contiene i nomi delli immagini che si trovano in Resources
        {
            PictureBox pb = new PictureBox();
            pb.Width = 120;
            pb.Height = 150;
            pb.SizeMode = PictureBoxSizeMode.StretchImage;
            Image img = Properties.Resources.ResourceManager.GetObject(myList[i]) as Image;
            pb.Image = img;
            pb.Tag = i;
            pb.Click += new System.EventHandler(this.PB_Click);
            flowLayoutPanel1.Controls.Add(pb);   //per mantenere le immagini allineate
        }
    }
    In questo modo pensavo di effettuare un controllo sulla proprietà Tag per capire quale carta è stata giocata, ma le pictureBox si chiamano tutte pb e ad ogni cilco viene aggironata la proprietà Tag di tutte le pictureBox create (in pratica alla fine mi ritrovo tutte le pictureBox con la proprietà Tag uguale al massimo valore di i). Perchè ciò avviene per la proprietà Tag mentre la proprietà Image funziona correttamente (non viene aggiornata ad ogni ciclo per tutte le pictureBox ma solo per quella interessata)? Ho provato anche a usare la proprietà Name ma stesso risultato (spero di essermi spiegato il meglio possibile). Come potrei fare per risolvere questo problema?
    Grazie a tutti.

  4. #4
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    Pb_Click l'hai creata? hai usato la stessa firma che ti ho postato io nel mio esempio? se si allora sender è l'oggetto che ha scatenato l'evento cioè la PictureBox cliccata. Poiche in firma è un object devi effettuare il cast a pictureBox per usarlo, per esempio:

    string tag = (sender as PictureBox).Tag;

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2011
    Messaggi
    24
    grazie mille rsdpzed,
    funziona perfettamente, è proprio quello di cui avevo bisogno.

    Mille grazie ancora, mi hai salvato la vita

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.