簡體   English   中英

圖片框一步一步工作正常,但執行時,似乎每次執行兩次定時器滴答

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM