Reputation: 21
I am writing a simple Ludus Latrunculorum game for my project at school and am using Picture Boxes in order to represent the pieces for the game.
However, when I use a background image - any background image for panel I am placing the piece at, it draws them very slowly. As if it places 1 picture top left, then waits about 0.005 and places the next one, until the board is filled.
I've tried replacing the background image with a 1x1 white image, same outcome.
BUT, when I make the background a color (this.board.BackColor = Color.Green;
) it prints the pieces immediately.
Furthermore, when I make the back color transparent, so I will see the original background of the whole form, once again, the print is very slow.
But when I use Color.Tan, which is my transparency key of the form, I see whatever is behind the form, and the pieces print immediately. Which I find very odd, as I am guessing it is more difficult for the CPU to fetch whatever is behind the form and print the pieces on it than it is to fetch the background image and print on that.
Why is that happening? How can I make the pictures print immediately?
Desired behaviour - Immediate print of the pieces. Actual behaviour - Slow print of the pieces. Short code to get same problem: Form1.Designer.cs
using System.Drawing;
namespace WindowsFormsApplication6
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackgroundImage = (Image)Image.FromFile(@"C:\Users\gold\Documents\Visual Studio 2013\Projects\Ludus Latrunculorum\Ludus Latrunculorum\images\Background.png", true); // Comment that and see how it prints the pictures immediately
this.ClientSize = new System.Drawing.Size(907, 595);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication6
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PrintBoard();
}
private PictureBox[,] piecesImg;
private void PrintBoard()
{
this.piecesImg = new PictureBox[8, 8];
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
{
this.piecesImg[i, j] = new PictureBox();
this.piecesImg[i, j].ClientSize = new Size(52, 52);
this.piecesImg[i, j].Image = (Image)Image.FromFile(@"C:\Users\gold\Documents\Visual Studio 2013\Projects\Ludus Latrunculorum\Ludus Latrunculorum\images\White Pawn.png", true);
this.piecesImg[i, j].BackColor = Color.Transparent;
this.piecesImg[i, j].Location = new Point(j * 57, i * 57);
this.Controls.Add(this.piecesImg[i, j]);
}
}
}
}
Upvotes: 1
Views: 4130
Reputation: 1892
My first advice is: don't use PictureBox
, bacuse this control is heavy. If you want to draw an image, just draw it in OnPaint
method.
Second advice: add all the images to Resources, so you will access them much easier just by name instead of full path.
And one more thing: remove the background. We will draw it as well. No need to set it. So, here's my full example.
Reources.resx
Form1.cs
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DoubleBuffered = true;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawImage(Properties.Resources.Background, 0, 0);
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
e.Graphics.DrawImage(Properties.Resources.Pawn, new Rectangle(j * 57, i * 57, 52, 52));
}
}
Application
Note that I set DoubleBuffered
flag in constructor to eliminate flickering.
Upvotes: 2
Reputation: 21
http://www.c-sharpcorner.com/Forums/Thread/45434/ solved the problem. Should have enabled doublebuffering and changed the layout to stretch.
Upvotes: 1