Sign in to follow this  
Fragsta

[.net] C# Obvious Question: Repaint

Recommended Posts

I'm pretty new to C# and I'm trying to figure out how I can repaint a form when some of the things which made the original image change. I have a square on the screen, and when I press W A S or D it moves in the appropriate direction. In theory, it does, and I've got the console to tell me it's location. But I can't get Form1 to repaint. I have a class called Ship, which has a DrawShip method (accepts Graphics _g) and the crucial line is here:
_g.DrawRectangle(new Pen(Color.Red), shipPos.X, shipPos.Y, imgShip.Width, imgShip.Height);
In Form1, where _g is sent from, we have in Form1_Paint, this:
Player1Ship = new Ship(20,20);
Player1Ship.DrawShip(g);
Then I click the S key to move it down and the ship's coordinates change:
private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.S:
                    Player1Ship.MoveDown();
                    break;
            }
        }
So at this point I want to redraw the image. This seems like an obvious thing to be able to do but I can't see a good way of doing it. Can anyone help me out please?

Share this post


Link to post
Share on other sites
Hi Fragsta!

Try to call Form1.Invalidate() after the user input:


case Keys.S:

Player1Ship.MoveDown();
Invalidate();

break;



Calling Form1.Invalidate() is the method I usually use when I develop a custom control in .NET; usually I would do something like this:

1) Process user input
2) Update the state
3) Call Invalidate()

This assumes that you are drawing from within the Paint handler, which is pretty much your case; I usually override OnPaint() method when I develop a custom control, while you registered a delegate; however it should make no difference: Invalidate() will trigger the event, and your Form1_Paint() should then be called.

Another little hint; setting Form1.DoubleBuffered to true should prevent flickering, in case you are experiencing it.

Bye, hopefully that will work!

Dario

Share this post


Link to post
Share on other sites
Quote:
Original post by damix911
Hi Fragsta!

Try to call Form1.Invalidate() after the user input:

*** Source Snippet Removed ***

Calling Form1.Invalidate() is the method I usually use when I develop a custom control in .NET; usually I would do something like this:

1) Process user input
2) Update the state
3) Call Invalidate()

This assumes that you are drawing from within the Paint handler, which is pretty much your case; I usually override OnPaint() method when I develop a custom control, while you registered a delegate; however it should make no difference: Invalidate() will trigger the event, and your Form1_Paint() should then be called.

Another little hint; setting Form1.DoubleBuffered to true should prevent flickering, in case you are experiencing it.

Bye, hopefully that will work!

Dario


Thanks Dario. Invalidate() actually appears to reset the state, oddly enough. Each time I press S, the output is Ship is now at Y21, X20, like so:

Ship is now at Y21, X20
Ship is now at Y21, X20
Ship is now at Y21, X20
Ship is now at Y21, X20


This happened with Refresh() too.

EDIT: In fact, it isn't resetting, because the original position is 20,20 - so it's going down once then stopping. No exceptions being thrown or any errors being reported, so I have no idea what's going on!

You mentioned use of a delegate; I'm not using any delegates here, unless C# is making one for me in a way I've not seen before. I haven't declared any, at least. Is that where I'm going wrong?

Share this post


Link to post
Share on other sites
If you have the following in the Paint() call then your creating a new ship object every call

Player1Ship = new Ship(20,20);


Instead of putting that in Form1_Paint put it in Form1_Load.

Share this post


Link to post
Share on other sites
I think Headkaze is right, the problem could be in the algorithm. I suspected there was something wrong in it however I focused on the Windows.Drawing issue. By the way, for what concern the delegates, Visual Studio does create a delegate when you associate an event to a component.

The following code draws a circle under the mouse cursor; set DoubleBuffered to true in the form properties to avoid flickering.


using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private int x;
private int y;

public Form1()
{
InitializeComponent();
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics gfx = e.Graphics;

gfx.Clear(Color.Black);
gfx.FillEllipse(new SolidBrush(Color.Red), new Rectangle(x - 3, y - 3, 7, 7));
}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
x = e.X;
y = e.Y;

Invalidate();
}
}
}



Bye!

Dario

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this