Benutzer mit den meisten Antworten
Steuerelement mit Arrays und Ereignisse

Frage
-
Hallo.
Ich habe zu Laufzeit ein Array mit PictureBoxen erstellt. Nennen wir sie mal Bild[x,x].
Wie rufe ich für diese jetzt z.B. das Ereigniss Click ab? Auf:
private void Bild_MouseClick(object sender, EventArgs e)
{
MessageBox.Show("teste");
}erfolgt keine Reaktion bei einem Mausklick auf die PicturBox.
Kann jemand helden?
Danke
Jan
Antworten
-
Hallo Jan,
verpasse den Bäumen Namen.
Jedes Steuerelement hat eine Name Eigenschaft - die ansonsten vom Designer genutzt wird.
Baum[1,1] = new PictureBox(); Baum[1, 1].Name = "Baum 1, 1"; Baum[1,2] = new PictureBox(); Baum[1, 2].Name = "Baum 1, 2";
Beachte dass ich jedesmal eine neue PictureBox erstelle, denn sonst kannst Du sie nicht unterscheiden.
Du kannst ihnen jedoch die gleiche Grafik über die Image-Eigenschaft zuweisen.Und den Namen kannst Du später verwenden und aus Holgers Code wird:
Eine weitere Variante wäre der Einsatz der Tag Eigenschaft, wo Du beliebiges hinterlegen kannst -private void OnBaumClick(object sender, EventArgs e) { var angeklickterBaum = sender as PictureBox; if (angeklickterBaum != null) { //mehr Code Console.WriteLine("Baum geklickt: " + angeklickterBaum.Name); }
z. B. die Baumart ;-)Gruß Elmar
- Als Antwort vorgeschlagen Stefan FalzModerator Sonntag, 3. Juli 2011 00:16
- Als Antwort markiert Bogdan Petru Roiu Mittwoch, 6. Juli 2011 10:25
Alle Antworten
-
-
Hallo Jan,
Tamlocar hat Recht, Du mußt für jede neue PictureBox-Instanz das entsprechende Ereignis abonnieren. Hier ein Beispiel, dass ein multidimensionales PictureBox-Array in ein TableLayoutPanel einliest und dabei für jedes PictureBox-Control einen OnClick-Handler hinzufügt:
using System; using System.Drawing; using System.Linq; using System.Windows.Forms; using System.IO; namespace WindowsFormsApplication1 { public partial class Form1 : Form { Button buttonFillLayoutPanel; TableLayoutPanel imagesLayoutPanel; public Form1() { InitializeComponent(); // Controls hinzufügen imagesLayoutPanel = new TableLayoutPanel { Dock = DockStyle.Fill }; buttonFillLayoutPanel = new Button { Text = "Bilddateien einlesen", Dock = DockStyle.Top }; buttonFillLayoutPanel.Click += OnButtonFillLayoutPanelClick; Controls.AddRange(new Control[] {imagesLayoutPanel, buttonFillLayoutPanel}); } void OnButtonFillLayoutPanelClick(object sender, EventArgs e) { // Image-Dateipfade ermitteln string imagePath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); string[] imageFiles = Directory.GetFiles(imagePath, "*.jpg", SearchOption.AllDirectories); int imageCount = imageFiles.Length; if (imageCount == 0) return; // Für Testzwecke Anzahl der Imagedateien auf 20 begrenzen if (imageCount > 20) { Array.Resize(ref imageFiles, 20); imageCount = 20; } // Zeilen- und Spaltenanzahl berechnen int rowCount = imageCount == 1 ? 1 : imageCount % 2 == 0 ? imageCount / 2 : (imageCount / 2) + 1; int columnCount = 2; // Evtl. vorhandene PictureBoxControls vom OnPictureBoxClick-Ereignishandler lösen var pictureBoxQuery = from p in imagesLayoutPanel.Controls.OfType<PictureBox>() select p; foreach (var pictureBox in pictureBoxQuery) pictureBox.Click -= OnPictureBoxClick; // TableLayoutPanel neu initialisieren und dimensionieren imagesLayoutPanel.RowStyles.Clear(); imagesLayoutPanel.Controls.Clear(); imagesLayoutPanel.RowCount = rowCount; imagesLayoutPanel.ColumnCount = columnCount; imagesLayoutPanel.AutoScroll = true; // Image-Dateien zum PictureBox[] bzw. zum TableLayoutPanel hinzufügen // OnClick-Ereignis abonnieren. PictureBox[,] pictureBoxArray = new PictureBox[rowCount, columnCount]; int imageIndex = 0; for (int rowIndex = 0; rowIndex < pictureBoxArray.GetLength(0); rowIndex++) { for (int columnIndex = 0; columnIndex < pictureBoxArray.GetLength(1); columnIndex++) { Image image = Image.FromFile(imageFiles[imageIndex]); PictureBox pictureBox = new PictureBox { Image = image, Tag = imageFiles[imageIndex], SizeMode = PictureBoxSizeMode.Zoom }; pictureBox.Click += OnPictureBoxClick; pictureBoxArray[rowIndex, columnIndex] = pictureBox; imagesLayoutPanel.Controls.Add(pictureBox, columnIndex, rowIndex); imageIndex++; } } } void OnPictureBoxClick(object sender, EventArgs e) { // Gespeicherten Dateinamen anzeigen PictureBox pictureBoxClicked = sender as PictureBox; if(pictureBoxClicked != null) { Image image = pictureBoxClicked.Image; if (image != null && pictureBoxClicked.Tag != null && pictureBoxClicked.Tag.GetType() == typeof(string)) { MessageBox.Show((string)pictureBoxClicked.Tag); } } } } }
Für einfache Informationen reicht die Behandlung von Control.Click. Möchtest Du erweiterte Maus-Informationen oder soll das Ereignis nicht auch durch die Eingabetaste ausgelöst werden können, kannst Du (seit .NET 2.0) Control.MouseClick verwenden.
Gruß
Marcel- Als Antwort vorgeschlagen Stefan FalzModerator Sonntag, 3. Juli 2011 00:16
-
Hallo Y.,
man geht die PictureBox'en einfach normal (zum Beispiel in einer for-Schleife) durch und subscribed (pro PictureBox) das Click-Ereignis.
Hier ein Beispiel:using System; using System.Drawing; using System.Windows.Forms; using System.Collections.Generic; namespace SteuerelementArrayDemo { public partial class Form1 : Form { const int anzahlBildBoxen = 10; const int höhePictureBox = 50; const int breitePictureBox = 50; Color geradeFarbe = Color.Green; Color ungeradeFarbe = Color.Red; TextBox txtInfo = new TextBox(); PictureBox[] pictureBoxen; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { pictureBoxen = DemoBildBoxenFüllen(); foreach (PictureBox box in pictureBoxen) box.Click += new EventHandler(box_Click); InformationsTextBoxZufügen(); } private PictureBox[] DemoBildBoxenFüllen() { FlowLayoutPanel flp = new FlowLayoutPanel(); flp.WrapContents = true; flp.Dock = DockStyle.Fill; List<PictureBox> boxen = new List<PictureBox>(); for (int i = 0; i < anzahlBildBoxen; i++) { PictureBox box = new PictureBox(); box.Width = breitePictureBox; box.Height = höhePictureBox; box.BackColor = (i % 2 == 0) ? geradeFarbe :ungeradeFarbe; box.Name = "box" + (i+1); boxen.Add(box); flp.Controls.Add(box); } Controls.Add(flp); return boxen.ToArray(); } void box_Click(object sender, EventArgs e) { Control ctl = sender as Control; if (ctl == null) return; txtInfo.AppendText("Geklickt auf: " + ctl.Name + "\r\n"); } private void InformationsTextBoxZufügen() { txtInfo.Dock = DockStyle.Bottom; txtInfo.Multiline = true; txtInfo.Height = 100; txtInfo.ScrollBars = ScrollBars.Both; Controls.Add(txtInfo); } } }
ciao Frank
- Als Antwort vorgeschlagen Stefan FalzModerator Sonntag, 3. Juli 2011 00:16
-
Und weiter geht es.
Ich muss dazu sagen, dass ich relativer Anfänger bin und mich schwer tue ein Buch von A bis Z durch zu abreiten da ich doch schon einiges weis und mir dann der Anfang in den Büchern immer auf die Nerven geht :-/ Bitte daher nicht übel nehmen ...
Ich habe mit
public PictureBox[,] Baum= new PictureBox[3,10];
public PictureBox pbxBaum = new PictureBox();zwei neue Pictureboxen zur Laufzeit erstellt und dann mit
pbxBaum.MouseHover += OnBaumMouseHover;
pbxBaum.Click += OnBaumClick;die Ereignisse zugeortnet und abschliessend dann per
Baum[1,1] = pbxBaum;
Baum[2,1] = pbxBaum;zwei neue PictureBoxen Baum[,] erstellet.
auf die Ereignisse reagiere ich mit
private void OnBaumClick(object sender, EventArgs e)
{
MessageBox.Show("geklickt");
}
private void OnBaumMouseHover(object sender, EventArgs e)
{
txtBox1.Text = "MouseHover";
}
Nun möchte ich aber in den Ereinissen wissen welcher "Baum" das Ereigniss ausgelöst hat. Um z.B. nach einem Click auf einen der Bäume "Du hast Baum Nr.: " + BaumNummer + " geklickt" über die MessageBox auszugeben.
Danke für die Hilfe
Jan
-
Hallo Yawahoo,
bitte beginne bei einer neuen Frage einen neuen Thread.
Bei Windows Forms erhälst du den Sender des Events über den Parameter "sender" eines jeden Events. Du musst "sender" nur noch in den richtigen Datentypen casten, und schon hast du das Objekt das den Event gefeuert hat.
private void OnBaumClick(object sender, EventArgs e) { PicutreBox angeklickterBaum = sender as PictureBox; if(angeklickterBaum != null) { //war cast erfolgreich? ... //mehr Code } }
Viele Grüße
Holger M. Rößler
Kaum macht man es richtig, schon funktioniert es -
-
Hallo Jan und Holger,
Ich beziehe mich jetzt auf den weiter oben von mir geposteten Code (wobei ich zusätzlich das PictureBox-Array zum Feld promotet habe):
void OnPictureBoxClick(object sender, EventArgs e) { PictureBox pictureBoxClicked = sender as PictureBox; if (pictureBoxClicked != null) { for (int rowIndex = 0; rowIndex < pictureBoxArray.GetLength(0); rowIndex++) { for (int columnIndex = 0; columnIndex < pictureBoxArray.GetLength(1); columnIndex++) { if(pictureBoxArray[rowIndex, columnIndex] == pictureBoxClicked) { MessageBox.Show(String.Format("{0},{1}", rowIndex, columnIndex )); return; } } } } }
Im Prinzip eine einfache Suche im Array, die auf manigfaltige Weise gestaltet und optimiert werden kann.
P.S. Im obigen Beispiel werden (nur zur Beruhigung) nicht die PictureBox-Inhalte miteinander verglichen, sondern die im Array gespeicherten Referenzen werden mit der übergebenen pictureBoxClicked-Referenz verglichen.5 ways for equality check in .net .. why? and which to use?
http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/84e2a419-f82a-494e-8723-ef01284d2cbc#a15a0a55-8616-4f7c-b4be-ef05b1b578bfGruß
Marcel- Als Antwort vorgeschlagen Stefan FalzModerator Sonntag, 3. Juli 2011 00:17
-
Hallo Jan,
verpasse den Bäumen Namen.
Jedes Steuerelement hat eine Name Eigenschaft - die ansonsten vom Designer genutzt wird.
Baum[1,1] = new PictureBox(); Baum[1, 1].Name = "Baum 1, 1"; Baum[1,2] = new PictureBox(); Baum[1, 2].Name = "Baum 1, 2";
Beachte dass ich jedesmal eine neue PictureBox erstelle, denn sonst kannst Du sie nicht unterscheiden.
Du kannst ihnen jedoch die gleiche Grafik über die Image-Eigenschaft zuweisen.Und den Namen kannst Du später verwenden und aus Holgers Code wird:
Eine weitere Variante wäre der Einsatz der Tag Eigenschaft, wo Du beliebiges hinterlegen kannst -private void OnBaumClick(object sender, EventArgs e) { var angeklickterBaum = sender as PictureBox; if (angeklickterBaum != null) { //mehr Code Console.WriteLine("Baum geklickt: " + angeklickterBaum.Name); }
z. B. die Baumart ;-)Gruß Elmar
- Als Antwort vorgeschlagen Stefan FalzModerator Sonntag, 3. Juli 2011 00:16
- Als Antwort markiert Bogdan Petru Roiu Mittwoch, 6. Juli 2011 10:25
-
Hallo Jan,
- ... Nun möchte ich aber in den Ereignissen wissen welcher "Baum" das Ereigniss ausgelöst hat.
ja, das ist aber u.a. bereits in meinem ersten Posting beispielhaft gezeigt, also eben beispielsweise über den Namen der PictureBox (in meinem Codebeispiel: "ctl.Name"). Wenn Du auf eine PictureBox klickst, kommt ja die Meldung, auf welche Box geklickt wurde.
ciao Frank