2015-07-17 2 views
1

У меня есть эта форма, содержащая 4 ярлыка. Я хочу, чтобы эти метки мигали с определенной частотой, например 12,5, 10, 8 и 4 Гц. Я использовал таймер, но он не будет работать правильно. Они мигают с гораздо меньшей частотой, я знаю, это потому, что вложенные if s в freqMethod ниже. Как мне решить эту проблему?мигающие этикетки backColor in C#

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Timers; 
using System.Threading; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     System.Timers.Timer mainTimer; 
     private int counter = 0; 
     Color lColor = Color.FromArgb(255, 192, 128); 
     bool buttonPressed = false; 

     public Form1() 
     { 

      InitializeComponent(); 
      label1.BackColor = lColor; 
      label2.BackColor = lColor; 
      label3.BackColor = lColor; 
      label4.BackColor = lColor; 
      mainTimer = new System.Timers.Timer(1); 
      mainTimer.Elapsed += new ElapsedEventHandler(timerElapsed); 
     } 


     private void button2_Click(object sender, EventArgs e) 
     { 
      if (buttonPressed) 
      { 
       mainTimer.Enabled = false; 
       buttonPressed = !buttonPressed; 
       counter = 0; 
      } 
      else 
      { 

       mainTimer.Enabled = true; 
       buttonPressed = !buttonPressed; 
       counter = 0; 
      } 
     } 

     //Frequency Method 

     public void freqMethod() 
     { 
      if (counter % 80 == 0) 
       if (label4.backColor == lColor) 
        label4.backColor = Color.black; 
       else 
        label4.backColor = lColor; 
      if (counter % 100 == 0) 
       if (label3.backColor == lColor) 
        label3.backColor = Color.black; 
       else 
        label3.backColor = lColor; 
      if (counter % 125 == 0) 
       if (label2.backColor == lColor) 
        label2.backColor = Color.black; 
       else 
        label2.backColor = lColor; 
      if (counter % 250 == 0) 
       if (label1.backColor == lColor) 
        label1.backColor = Color.black; 
       else 
        label1.backColor = lColor; 



     } 
     private void timerElapsed(object source, ElapsedEventArgs e) { 
      counter++; 
      freqMethod(); 
     } 

    } 
} 

ответ

1

Вам не нужно таймер для итерации каждый второй, как вы пропустите это каждые n итераций в то время как они занимают слишком много ресурсов. Вы можете просто манипулировать значением TimerInterval, чтобы получить требуемую частоту с производительностью adeqate.

Например, для частоты 8 Гц требуется только таймер для запуска события каждые 125 мс (8 раз в секунду).
Я приведу пример с частотой double, чтобы он работал с интервалами < 1. Например, если вы установили частоту 0.5, цвет будет меняться каждые 2 секунды.

Пример:

public Form1() 
{ 
    double frequencyInHz = 8.0; // here goes your frequency 
    int interval = (int)Math.Round(1000.0/frequencyInHz); // 125ms in this case 
    mainTimer = new Timer(interval); 
    mainTimer.Elapsed += new ElapsedEventHandler(timerElapsed); 
} 

private void timerElapsed(object source, ElapsedEventArgs e) { 
    if (label2.BackColor == lColor) 
     label2.BackColor = Color.Black; 
    else 
     label2.BackColor = lColor; 
} 

Если вам нужно несколько ярлыков, чтобы изменить их цвет с другой, вам нужно будет сделать несколько таймеров, чтобы получить хорошую производительность.

+0

Помните, что минимальный интервал этого таймера составляет 15 мс, если я не ошибаюсь. – Jens

+0

таким образом, я думаю, я должен использовать несколько таймеров, или, есть лучший способ сделать это? – user4949420

+0

@ user4949420 Да. На мой взгляд, это самый peformant-подход. Конечно, если у вас есть соответствующее количество меток и таймеров - например, 4 или 5. –

1

Попробуйте это (в дополнение к таймеру изменение интервала, предложенного Joel или Yeldar):

if (counter % 80 == 0) 
{ 
    label4.backColor = label4.backColor == lColor ? Color.black : lColor; 
    label4.Refresh() ; 
} 
+0

, я видел что-то подобное в другом месте, что означает эта линия? ярлык4.backColor = этикетка4.backColor == lColor? Color.black: lColor; – user4949420

+1

«x = BoolCondition? A: b» - это компактный способ кодирования «if (BoolCondition) x = a; else x = b;» – Graffito

2

Учитывая следующие значения (и если вы хотите, чтобы синхронизировать их с помощью одного таймера) общего интервала они могут иметь составляет 5 мс. Поэтому вам нужно пометить таймер 5 мс каждый и проверить частоту. Но обратите внимание на использование таймера, как описано ниже:

12.5hz = 80ms 
10hz = 100ms 
8hz = 125ms 
4hz = 250ms 

Заметки из MSDN с помощью System.Timers.Timer (https://msdn.microsoft.com/en-us/library/system.timers.timer.interval(v=vs.110).aspx) См замечания раздел.

Вы используете Interval свойство, чтобы определить частоту, при которой Уволен Прошедшее событие. Поскольку класс Timer зависит от системных часов , он имеет такое же разрешение, что и системные часы. Это означает, что Истекшее событие будет срабатывать с интервалом, определяемым разрешением системного тактового сигнала , если свойство Interval меньше разрешения системных часов . Следующий пример устанавливает свойство Интервал в 5 миллисекунд. При запуске в системе Windows 7 которой системные часы имеют разрешение примерно 15 миллисекунд, костров событий примерно каждые 15 миллисекунд, а не каждые 5 миллисекунд

Но если вы можете использовать несколько таймер для каждого, а затем вы можете установить каждый интервал таймера, как упоминалось в Yeldar.

Смежные вопросы