Autor Beitrag
Wayne_300
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Fr 04.05.12 11:14 
Hallo zusammen,

ich muss für die Schule ein eigens Projekt entwickeln. Ich hatte mich für Schiffe versenken entschieden. Das Ganze ist eine Windows-Forms Anwendung.

Für das Spielfeld habe ich eine Liste erstellt erstellt. In der Liste befinden sich 100 Bitmap Objekte(Die Kästen des Spielfeldes). Diese Objekte werden dann gezeichnet. Soweit so gut. Nun soll durch einen Mouse-Klick auf ein Feld, das passende Objekt gefunden werden, damit ich es dann durch ein anderes Bitmap-Objekt ersetzen kann (z.B. ein Bild mit einem Kreuz, für ein falsches Feld).

Meine Frage ist nun, wie kann ich durch einen Mouse-Click herausfinden, ob die gezeichnete Fläche, auf die ich geklickt habe, ein Objekt enthält und wenn ja, welchen Platz es in der Liste hat?

Ich hoffe ich habe mir klar genug ausgedrückt Augenzwinkern Bei Fragen einfach melden.

Danke im Voraus!

Gruß

Wayne

PS: Es sind keine WinForms Elemente.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 04.05.12 11:22 
Hallo Wayne :welcome:

wie herbivore in deinem Cross-Post unter myCSharp.de - Winforms - durch Mausklick bestimmte Objekte herausfinden schon geschrieben hat, ist dies doch nur ein einfacher Dreisatz:
ausblenden C#-Quelltext
1:
2:
int x = (e.X - OffsetX) / BitmapSizeX;
int y = (e.Y - OffsetY) / BitmapSizeY;

Wenn deine Bitmap-Objekte in einer eindimensionalen Liste (anstatt in einer 2D-Liste) sind, dann erhältst du den Index über:
ausblenden C#-Quelltext
1:
int listIndex = (y * 10) + x;					
Wayne_300 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Fr 04.05.12 11:35 
Es tut mir leid, vielleicht stelle ich mich im Moment etwas dumm an, aber ich verstehe nicht genau wie dieser Dreisatz funktioniert. Könntest du den noch mal erklären? Ich verstehe nicht wie ich daraus entnehmen kann das ich auf ein Objekt geklickt habe und an welcher Stelle dieses Objekt dann in der Liste stehen soll.

Jo, sind in einer eindimensionalen Liste vom Typ Bitmap.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 04.05.12 11:46 
Hallo,

OffsetX/OffsetY sind der Abstand vom linken bzw. oberen Rand (falls du nicht direkt bei (0/0) angefangen hast zu zeichnen) und BitmapSizeX/Y ist die Größe deiner gezeichneten Bitmaps.
Ob du überhaupt auf ein Bitmap geklickt hast, kriegst du dann raus, ob die x- und y-Werte innerhalb des erlaubten Bereichs (0-9) sind (aus 100 Bitmaps hast du ja ein 10x10 Raster gezeichnet).
Und durch die Indexberechnung erhältst du dann einen Wert von 0 bis 99, der also dann den Index innerhalb deiner Bitmap-Liste darstellt.

Wenn du dann eine Bitmap ausgetauscht hast, dann mußt du ja das Spielfeld neu zeichnen lassen - dazu dann einfach im Mouse-Click Ereignis
ausblenden C#-Quelltext
1:
Invalidate();					

aufrufen (dies ruft dann dein Paint-Ereignis neu auf).

Für diesen Beitrag haben gedankt: Wayne_300
Wayne_300 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Fr 04.05.12 12:26 
Danke ;)

Auf den Dreisatz und die Berechnung des Index wäre ich nie gekommen... Wie seid ihr darauf gekommen?
Wayne_300 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Fr 04.05.12 12:56 
Ein Problem habe ich noch. Wenn ich Validate() im Mouse-Click Eventhandler aufrufe, wird das Formular nicht neu gezeichnet. Erst wenn ich die Form minimiere, verkleinere usw.
Was kann ich tun?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 04.05.12 13:32 
Nicht Validate(), sondern Invalidate()! (die beiden Methoden haben nichts miteinander zu tun, auch wenn sie sich nur im Prefix unterscheiden)
Wayne_300 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Fr 04.05.12 13:52 
Oh sry, ich hatte mich nur verschrieben :-D Ich habe Invaladate() gemeint. Wie gesagt, es passiert erst etwas, wenn das Spielfeld verschwindet und wieder auftaucht, aber nach einem Klick auf ein Feld wird nicht neu gezeichnet.
Auch mir Refresh() klappt es nicht. Gibt es eine Möglichkeit, dass bei einem Klick neugezeichnet wird?
mats74
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 189
Erhaltene Danke: 26

Win 10
VS 2017/19, C++, C#
BeitragVerfasst: Fr 04.05.12 14:06 
ausblenden C#-Quelltext
1:
this.Invalidate();					

... zeichnet definitiv das Form neu, sofern der this-Zeiger auf das Formobjekt zeigt.
Also einfach im Click-Ereigniss eingeben und ausprobieren.

_________________
Gruss
mats74
Wayne_300 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Fr 04.05.12 14:19 
Okay, ihr hattet recht. Ich habe Invalidate() aus einer anderen Klasse heraus aufgerufen und das hatte nicht funktioniert. Eine andere Frage hätte ich noch, wenn neu gezeichnet wird, flackert das Bild kurz, kann man dagegen was machen? (DoubleBuffered funktioniert ja nur bei Steuerelementen und nicht bei gezeichneten Objekten oder?)
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 04.05.12 14:34 
Setze einfach DoubleBuffered für deine Form-Klasse, am besten direkt im Konstruktor
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
MyForm()
{
  InitializeComponent();

  DoubleBuffered = true;
}
Wayne_300 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Fr 04.05.12 14:39 
Ich zeichne in einem Panel. Ein Panel hat diese Eigenschaft leider nicht, also muss ich ne eigene Klasse schreiben und sie von Panel ableiten. Das müsste funktionieren oder?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 04.05.12 14:41 
Oder alternativ mittels "Reflection" setzen, s. z.B. www.csharp-examples.net/set-doublebuffered
Wayne_300 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Fr 04.05.12 15:28 
Okay, dankeschön :) Ihr wart mir eine große Hilfe ;)