C# overridden OnPaint seems to have multiple copies
Posted: Mon Apr 13, 2009 7:38 pm
So if I trace this, after the return; in the win condition (put there for testing) I pick up in the middle of the function somewhere, but only if I have a breakpoint. This leads me to believe that I somehow have multiple copies of OnPaint running. In other words, I'll be inside the gameHasStarted check with gameHasStarted being false. This does not occur on a Windows XP (VM on a Mac), but it does happen on my native Windows Vista. Any ideas on how this could happen?
No critiques on the function, please. I didn't write it. One of my group members did.
No critiques on the function, please. I didn't write it. One of my group members did.
Code: Select all
/// <summary>
/// Anytime we need to redraw the screen, OnPaint will be called.
/// Our overrided version will take care of drawing the correct number
/// of cards we want to the screen, and then calls the base version to
/// take care of everything else.
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
if (gameHasStarted) //This *MUST* be here -- as opposed to a !...return, or it won't work on Vista (seriously what the heck)
{
// We only do pictureBox stuff if the game has started
// if i have called set or there are selected pictureBoxCalledSeten, then set is invisible
bSet.Visible = !(selectedPictureBoxes.Count > 0 || localCalledSet);
//Tell gameHandler to gimme some cards
list = gameHandler.displayCards(numberOfCardsToBeDisplayed);
if (list.Count == 0) // endgame condition
{
if (!announcedWinner) //only display the win once
{
announcedWinner = true;
if (theProject.Form1.gameHandler.exitCurGame(highScores) == 0) //win condition
{
// oh mi gawd!
MessageBox.Show(gameHandler.getWinner() + " won the game.", "Game Over");
initGame();
System.Diagnostics.Debug.WriteLine(Environment.OSVersion.ToString());
//this.Dispose(); //If we can't find out what's causing what seems like multiple OnPaints in Vista, check above & do this
return;
}
//bHint.Visible = true;
}
}
else // if the game is not over...
{
// If we need to draw more cards && we have more cards to draw
while ((numberOfCardsToBeDisplayed != cardsOnScreen.Count) && list.Count == numberOfCardsToBeDisplayed)
{
scrollVal = panel1.HorizontalScroll.Value;
// If we're going to draw some extra cards, just reposition that Horizontal scroll bar
panel1.HorizontalScroll.Value = 0;
// Then we add more cards to the screen.
addThreeCards();
bHint.Visible = false;
}
// However, if we have more cards on the screen than we have cards,
// we need to remove some pictureBoxes.
bool redrawPanel = false;
while (cardsOnScreen.Count > list.Count)
{
redrawPanel = true;
// Let's remove the picture box
panel1.Controls.RemoveAt(panel1.Controls.Count - 1);
// And decrement the count
cardsOnScreen.RemoveAt(cardsOnScreen.Count - 1);
}
if (redrawPanel) //Only redraw when necessary, otherwise it looks terrible
panel1.Invalidate();
// Draw those suckers to the screen.
for (int i = 0; i < cardsOnScreen.Count; i++)
{
PictureBox pb = (PictureBox)cardsOnScreen[i];
pb.Image = null;
pb.BackgroundImage = null;
pb.Name = list.ElementAt(i).cardNum.ToString();
// Set the color of the card
switch (list.ElementAt(i).color)
{
case 0: pb.BackColor = Color.Blue;
break;
case 1: pb.BackColor = Color.Red;
break;
case 2: pb.BackColor = Color.Green;
break;
}
// Since we have slightly different backgrounds for each shape, and for each of the
// number of different shapes on the card, we need to do the background here too.
switch (list.ElementAt(i).shape)
{
// oval
case 0: pb.Image = ovalForeground[list.ElementAt(i).number];
if (list.ElementAt(i).shade == 1)
{
pb.BackgroundImage = ovalBackground[list.ElementAt(i).number % 2];
}
break;
// rect
case 1: pb.Image = rectForeground[list.ElementAt(i).number];
if (list.ElementAt(i).shade == 1)
{
pb.BackgroundImage = rectBackground[list.ElementAt(i).number % 2];
}
break;
// star
case 2: pb.Image = starForeground[list.ElementAt(i).number];
if (list.ElementAt(i).shade == 1)
{
pb.BackgroundImage = starBackground[list.ElementAt(i).number % 2];
}
break;
}
// By default, the shade will be solid (type 0)
if (list.ElementAt(i).shade == 2)
{
pb.BackgroundImage = shadeBackground;
}
}
// Repaint the scores to the screen.
lBScores.Items.Clear();
string scores = gameHandler.getScores();
string[] split = scores.Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < split.Length; i++)
{
lBScores.Items.Add(split[i]);
}
}
// Let Windows do its own paint stuff.
// base.OnPaint(e);
}
}