Gå til innhold

C#: Problem med Graphics object, får ArgumentException


Anbefalte innlegg

Tenkte jeg skulle lage et Snake-spill for moro skyld, men det viste seg å ikke være så rett fram som jeg først trodde.

 

Her er et lite kodeeksempel jeg satt sammen:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace testDrawing
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm
{
 [STAThread]
 public static void Main(string[] args)
 {
 	Application.EnableVisualStyles();
 	Application.SetCompatibleTextRenderingDefault(false);
 	Application.Run(new MainForm());
 }
 Graphics g;
 public MainForm()
 {
 	InitializeComponent();
 }
 
 void MainFormPaint(object sender, System.Windows.Forms.PaintEventArgs e)
 {
 	g = e.Graphics;
 	MyFunc();
 	
 	g.DrawString("Heisann!", new Font("Trebuchet MS", 21), Brushes.DarkGreen,
               new Point(10, 10));
 }
 void MyFunc()
 {
 	g.DrawString("Heisann!", new Font("Trebuchet MS", 25), Brushes.DarkGreen,
               new Point(100, 40));
 }
 
 void MainFormKeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
 {
 	g.DrawString("Heisann!", new Font("Trebuchet MS", 25), Brushes.DarkGreen,
               new Point(110, 40));
 }
}
}

Det er akkurat dette jeg prøver på i spillet også, å tegne med Graphics objektet i en keypress event handler. Hvorfor funker ikke det?

 

Det som skjer i denne koden er at den skriver "Heisann!" 2 ganger, og hvis jeg trykker på en knapp får jeg et ArgumentException:

Exception System.ArgumentException was thrown in debuggee:
Parameter is not valid.

CheckErrorStatus()
DrawString()
DrawString()
MainFormKeyPress() - c:\Documents and Settings\*****\Mine dokumenter\SharpDevelop Projects\testDrawing\MainForm.cs:58,4
OnKeyPress()
ProcessKeyEventArgs()
ProcessKeyMessage()
WmKeyChar()
WndProc()
WndProc()
WndProc()
WndProc()
OnMessage()
WndProc()
DebuggableCallback()
System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop()
RunMessageLoopInner()
RunMessageLoop()
Run()
Main() - c:\Documents and Settings\*****\Mine dokumenter\SharpDevelop Projects\testDrawing\MainForm.cs:27,4

Endret av JeyKey
Lenke til kommentar
Videoannonse
Annonse

Det du gjør feil her er at du bruker et Graphics objekt som ikke er initialisert uten at paint-eventen er utført. Her er et eksempel på hvordan du kan gjøre det:

 

private void Form1_Paint(object sender, PaintEventArgs e)
{
   Graphics g = e.Graphics;
   g.DrawString("Heisann!", new Font("Trebuchet MS", 21), Brushes.DarkGreen,
                new Point(10, 10));
   MyFunc(g);
}

private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
   // Send en paint message til kontrollen
   Invalidate();
}

private void MyFunc(Graphics g)
{
   // mer tegning her
}

Endret av Magellan
Lenke til kommentar

Invalidate() fører til at paint-beskjeden blir sendt til kontrollen, men jeg skjønner ikke hvordan det hjelper meg :dontgetit: Det fører bare til at objektet tegner på nytt, men jeg ønsker at hver gang en bruker trykker på en viss knapp, skal snaken min begynne å bevege seg i den retningen. Uansett hvordan jeg snur og vender på problemet mitt er det umulig å tegne til en kontroll fra en key press event ? Mulig jeg er litt treig i oppfattelsen, men ser ikke hvordan Invalidate() kan hjelpe meg med dette

 

Hvis du derimot klarer å flytte den "mer tegning her"-delen din til Form1_KeyPress har du løst problemet mitt :)

 

EDIT: vent litt med å svare, skjønte hvordan Invalidate metoden din kunne brukes ja :thumbup: Sier ifra hvis jeg står fast jeg :p

Endret av JeyKey
Lenke til kommentar

Ok, det du kan gjøre er for eksempel å lage et slange objekt som har egenskaper som posisjon og retning. I keypress eventen din kan du da for eksempel ha noe som dette (Directions er her en enumeration):

 

void MainFormKeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
 switch (e.KeyCode)
 {
     case Keys.Up:
         snake.Direction = Directions.Up;
         break;
     case Keys.Down:
         snake.Direction = Directions.Down;
         break;
     case Keys.Right:
         snake.Direction = Directions.Right;
         break;
     case Keys.Left:
         snake.Direction = Directions.Left;
         break;
     default:
         snake.Direction = Directions.Up;
         break;
 }
 Invalidate();
}

 

I paint eventen kan du da for eksempel kalle en tegne funksjon som er implementert i slange objektet.

 

private void MainForm_Paint(object sender, PaintEventArgs e)
{
   snake.Draw(e.Graphics);
}

 

Håper du skjønte tankegangen min her. Er litt trøtt så akkurat nå er jeg ikke så flink til å forklare.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...