|
Hi,
I bet there must be an elegant solution for this, I have seen codes trying to draw the gif over the datagridview cell of course the result is disastrous. Although it's no very clear for me, creating a custom column (picture column instead image column) looks like the right approach, can anybody help me with this?.
Thanks in advance. | | George Waters Thursday, August 27, 2009 10:20 AM | Hi George Waters,
From my experience, there are two methods to solve your issue:
1. Call some methods of the ImageAnimator class to update the frame of each image in the image cell. This is a code snippet:
//The index of the gif image column.
int IMAGE_COL_INDEX = 0;
//Whether the animation starts.
bool currentlyAnimating = false;
private void GifShowForm_Load(object sender, EventArgs e)
{
//Initial the data source here.
//Refresh the images.
this.dataGridView1.Paint += new PaintEventHandler(dataGridView1_Paint);
}
void dataGridView1_Paint(object sender, PaintEventArgs e)
{
//Begin the animation.
AnimateImage();
//Update the frames. The cell would paint the next frame of the image late on.
ImageAnimator.UpdateFrames();
}
//This method begins the animation.
public void AnimateImage()
{
if (!currentlyAnimating)
{
//Begin the animation.
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
if (row.IsNewRow == false)
{
Image img = row.Cells[IMAGE_COL_INDEX].Value as Image;
if (img != null)
{
ImageAnimator.Animate(img, new EventHandler(this.OnFrameChanged));
}
}
}
currentlyAnimating = true;
}
}
private void OnFrameChanged(object o, EventArgs e)
{
//Force a call to the Paint event handler.
this.dataGridView1.Invalidate();
}
You can get more information and a sample about ImageAnimator from: http://msdn.microsoft.com/en-us/library/system.drawing.imageanimator.animate.aspx.
2. Add a PictureBox for each image cell to show the gif animation. This is a code snippet:
//The index of the gif image column.
int IMAGE_COL_INDEX = 0;
//A timer to refresh the images.
Timer _timer = new Timer();
Dictionary<int,PictureBox> _pictureBoxes = null;
private void GifShowForm_Load(object sender, EventArgs e)
{
//Intial the data source of the DataGridView here.
//Add a PictureBox for each image cell.
AddAnimatedImages();
//Handle these two events to refresh picturebox's bounds.
this.dataGridView1.RowHeightChanged += new DataGridViewRowEventHandler(dataGridView1_RowHeightChanged);
this.dataGridView1.ColumnWidthChanged += new DataGridViewColumnEventHandler(dataGridView1_ColumnWidthChanged);
//The time interval to refresh the image.
//We can also consider it as animation speed.
//Decrease this value to speed the animation.
_timer.Interval = 100;
_timer.Tick += new EventHandler(_timer_Tick);
_timer.Start();
}
void dataGridView1_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
{
RefreshPictureBounds();
}
void dataGridView1_RowHeightChanged(object sender, DataGridViewRowEventArgs e)
{
RefreshPictureBounds();
}
//Refresh picturebox's bounds.
private void RefreshPictureBounds()
{
if (_pictureBoxes != null)
{
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
if(_pictureBoxes.ContainsKey(row.Index))
_pictureBoxes[row.Index].Bounds = this.dataGridView1.GetCellDisplayRectangle(IMAGE_COL_INDEX, row.Index, true);
}
}
}
void _timer_Tick(object sender, EventArgs e)
{
//Refresh the DataGridView to animate the images.
this.dataGridView1.Refresh();
}
//Add a picture box for each image cell.
private void AddAnimatedImages()
{
_pictureBoxes = new Dictionary<int, PictureBox>();
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
PictureBox picBox = new PictureBox();
//Set picturebox's bounds to image cell's bounds
picBox.Bounds = this.dataGridView1.GetCellDisplayRectangle(IMAGE_COL_INDEX, row.Index,true);
Image img = row.Cells[IMAGE_COL_INDEX].Value as Image;
if (img != null)
{
picBox.Image = img;
}
this.dataGridView1.Controls.Add(picBox);
_pictureBoxes.Add(row.Index, picBox);
}
}
Let me know if this helps. Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. - Marked As Answer byAland LiMSFT, ModeratorThursday, September 03, 2009 8:32 AM
-
| | Aland Li Monday, August 31, 2009 9:20 AM | For those who have the same blinking problem, I found a work around, just change the frame time equally:
Frame 1 = 50ms Frame 2 = 50ms
=) - Marked As Answer byGeorge Waters Saturday, September 05, 2009 9:13 PM
-
| | George Waters Saturday, September 05, 2009 9:13 PM | Hi George Waters,
From my experience, there are two methods to solve your issue:
1. Call some methods of the ImageAnimator class to update the frame of each image in the image cell. This is a code snippet:
//The index of the gif image column.
int IMAGE_COL_INDEX = 0;
//Whether the animation starts.
bool currentlyAnimating = false;
private void GifShowForm_Load(object sender, EventArgs e)
{
//Initial the data source here.
//Refresh the images.
this.dataGridView1.Paint += new PaintEventHandler(dataGridView1_Paint);
}
void dataGridView1_Paint(object sender, PaintEventArgs e)
{
//Begin the animation.
AnimateImage();
//Update the frames. The cell would paint the next frame of the image late on.
ImageAnimator.UpdateFrames();
}
//This method begins the animation.
public void AnimateImage()
{
if (!currentlyAnimating)
{
//Begin the animation.
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
if (row.IsNewRow == false)
{
Image img = row.Cells[IMAGE_COL_INDEX].Value as Image;
if (img != null)
{
ImageAnimator.Animate(img, new EventHandler(this.OnFrameChanged));
}
}
}
currentlyAnimating = true;
}
}
private void OnFrameChanged(object o, EventArgs e)
{
//Force a call to the Paint event handler.
this.dataGridView1.Invalidate();
}
You can get more information and a sample about ImageAnimator from: http://msdn.microsoft.com/en-us/library/system.drawing.imageanimator.animate.aspx.
2. Add a PictureBox for each image cell to show the gif animation. This is a code snippet:
//The index of the gif image column.
int IMAGE_COL_INDEX = 0;
//A timer to refresh the images.
Timer _timer = new Timer();
Dictionary<int,PictureBox> _pictureBoxes = null;
private void GifShowForm_Load(object sender, EventArgs e)
{
//Intial the data source of the DataGridView here.
//Add a PictureBox for each image cell.
AddAnimatedImages();
//Handle these two events to refresh picturebox's bounds.
this.dataGridView1.RowHeightChanged += new DataGridViewRowEventHandler(dataGridView1_RowHeightChanged);
this.dataGridView1.ColumnWidthChanged += new DataGridViewColumnEventHandler(dataGridView1_ColumnWidthChanged);
//The time interval to refresh the image.
//We can also consider it as animation speed.
//Decrease this value to speed the animation.
_timer.Interval = 100;
_timer.Tick += new EventHandler(_timer_Tick);
_timer.Start();
}
void dataGridView1_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
{
RefreshPictureBounds();
}
void dataGridView1_RowHeightChanged(object sender, DataGridViewRowEventArgs e)
{
RefreshPictureBounds();
}
//Refresh picturebox's bounds.
private void RefreshPictureBounds()
{
if (_pictureBoxes != null)
{
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
if(_pictureBoxes.ContainsKey(row.Index))
_pictureBoxes[row.Index].Bounds = this.dataGridView1.GetCellDisplayRectangle(IMAGE_COL_INDEX, row.Index, true);
}
}
}
void _timer_Tick(object sender, EventArgs e)
{
//Refresh the DataGridView to animate the images.
this.dataGridView1.Refresh();
}
//Add a picture box for each image cell.
private void AddAnimatedImages()
{
_pictureBoxes = new Dictionary<int, PictureBox>();
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
PictureBox picBox = new PictureBox();
//Set picturebox's bounds to image cell's bounds
picBox.Bounds = this.dataGridView1.GetCellDisplayRectangle(IMAGE_COL_INDEX, row.Index,true);
Image img = row.Cells[IMAGE_COL_INDEX].Value as Image;
if (img != null)
{
picBox.Image = img;
}
this.dataGridView1.Controls.Add(picBox);
_pictureBoxes.Add(row.Index, picBox);
}
}
Let me know if this helps. Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. - Marked As Answer byAland LiMSFT, ModeratorThursday, September 03, 2009 8:32 AM
-
| | Aland Li Monday, August 31, 2009 9:20 AM | Hi George,
Could you please let me know if my reply helps.
Regards, Aland Li Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. | | Aland Li Tuesday, September 01, 2009 3:50 AM | Thanks Aland, I'll try to test your code tomorrow and I'll let you know the result. | | George Waters Tuesday, September 01, 2009 5:01 AM | Aland
Thanks !!!, Your code works nice, but not perfectly, I used your fisrt option since i don't want to use a Timer. The problem is that the image does not blink perfectly, my gif has two frames: one with 70ms and the other with 30ms, but it blinks without respecting frame time. what would you suggest ?
Thanks again for your time buddy. | | George Waters Friday, September 04, 2009 11:13 PM | For those who have the same blinking problem, I found a work around, just change the frame time equally:
Frame 1 = 50ms Frame 2 = 50ms
=) - Marked As Answer byGeorge Waters Saturday, September 05, 2009 9:13 PM
-
| | George Waters Saturday, September 05, 2009 9:13 PM |
|