[英]pictureBox works fine step by step, but when executed, it seems to execute the timer tick twice each time
我正在制作一個簡單的屏幕保護程序,它顯示一組圖片,在全部顯示之前不重復它們。 問題是,pictureBox 正在跳過一些更新或其他東西,或者在兩張圖片之間快速切換。 其他時候,它會在同一個圖像上停留太久。
它在調試模式下工作得很好,即使我多次點擊繼續,除非我點擊繼續太快。
圖片框更新與每 2 秒觸發一次的計時器相關聯。
private void timer1_Tick(object sender, EventArgs e)
{
if (pictureBox1.Image != null) { pictureBox1.Image.Dispose();}
pictureBox1.Image = (Image)siguienteImagenAMostrar.Clone();
//siguienteImagenAMostrar is an Image, and it´s the one i want to show next
pictureBox1.Invalidate();
pictureBox1.Update();
if (siguienteImagenAMostrar != null) { siguienteImagenAMostrar.Dispose(); }
siguienteImagenAMostrar = siguienteImagen(); //I try to preload the Image
}
這是 siguienteImagen() 代碼,以防它與我使用的Random
有關:
private Image siguienteImagen()
{
int imagenAmostrar;
do
{
imagenAmostrar = rand.Next(0, files.Length);
} while (currentImage == imagenAmostrar && files.Length > 1);
int original = imagenAmostrar;
if (mostrada[imagenAmostrar]) {
imagenAmostrar = (imagenAmostrar + 1) % files.Length;
while (mostrada[imagenAmostrar] && original != imagenAmostrar)
{
imagenAmostrar = (imagenAmostrar + 1) % files.Length;
}
if (imagenAmostrar == original)
{
mostrada = Enumerable.Repeat(false, files.Length).ToArray();
}
}
mostrada[imagenAmostrar] = true;
currentImage = imagenAmostrar;
string imagenMostrarString = files[imagenAmostrar];
return Image.FromFile(imagenMostrarString);
}
編輯:這個 function 似乎不是問題,因為只需選擇下一個圖像作為currentImage = (currentImage + 1) % files.Length
仍然存在無法正確顯示圖片的問題。
mostrada
也是一個 bool 數組,它知道該圖片是否已經顯示。 files
是一個包含圖片路徑的數組。 相同的索引表示兩者上的相同圖像。
我敢打賭,如果您避免獲得可能已經使用過的隨機數,它將使您的代碼更清晰,並且為您和執行工作更少。 使用 Boolean 的數組來跟蹤這可能會浪費循環時間,因為隨機數生成器可能會生成已選擇的值。 我想你會想避免這種情況。
一種可能的解決方案是從圖像集合中創建索引的List<int>
。 例如圖像集合有五 (5) 張圖像,那么這個列表看起來像……。
Index value
0 0
1 1
2 2
3 3
4 4
我們想要“保留”一份這份清單的副本,因為在我們通過所有圖像 go 之后我們將需要它。 所以讓我們說第一個隨機數來自rand.Next(0, listAbove.Count);
是 3。然后我們將從索引 3 中獲取值,這也是索引三 (3)。 我們在索引三 (3) 處獲取圖像並從列表中“刪除”三 (3)。 在此之后,列表看起來像......
Index value
0 0
1 1
2 2
3 4
以這種方式繼續,直到列表為空,此時我們只需重新填充它。
鑒於這會創建兩個List<int>
變量......
List<int> fullImageListIndexes;
List<int> currentImageIndexes;
Random rand = new Random();
現在我們想要一個從這個列表中返回隨機圖像的方法。 隨機調用的邊界將為零 (0) 到列表的大小。 在我們找到一個隨機索引之后,我們將它從列表中“刪除”。 這將減小列表大小並保證始終只有一 (1) 次調用隨機數生成器。 以這種方式繼續,我們只需要檢查圖像列表是否為空,這表明我們已經使用了所有圖像並且需要用原始值“重新填充”列表。 我希望這是有道理的。
如上所述返回下一個隨機圖像的方法如下……首先檢查列表是否為空,如果是,只需重新填充它。 根據列表的大小獲取下一個隨機索引,獲取原始圖像的索引值,然后獲取該圖像,最后“移除”我們剛剛使用的圖像索引。
private Image GetNextRandomImage() {
if (currentImageIndexes.Count == 0) {
//textBox1.Text += "Refill" + Environment.NewLine;
currentImageIndexes = new List<int>(fullImageListIndexes);
}
int randomIndex = rand.Next(0, currentImageIndexes.Count);
int valueToRemove = currentImageIndexes[randomIndex];
Image nextImage = imageList1.Images[valueToRemove];
currentImageIndexes.Remove(valueToRemove);
//textBox1.Text += "Tick : RI: " + randomIndex + " SV: " + valueToRemove + Environment.NewLine;
return nextImage;
}
計時器滴答事件…
private void timer1_Tick(object sender, EventArgs e) {
pictureBox1.Image = GetNextRandomImage();
}
最后把它們放在一起...... imageList1
是一個 .Net 圖像列表 object,其中添加了一些圖像到其圖像集合中......
public Form1() {
InitializeComponent();
fullImageListIndexes = new List<int>();
for (int i = 0; i < imageList1.Images.Count; i++) {
fullImageListIndexes.Add(i);
}
currentImageIndexes = new List<int>(fullImageListIndexes);
}
希望這是有道理的。
發生的事情是我有timer1.Tick += new EventHandler(timer1_Tick);
在form_load()
function 中。 我仍然不確定為什么它在逐步模式下工作
刪除我擁有的明顯額外的 EventHandler 解決了我的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.