2012-04-19 5 views
2

잘 따르는 데 그리 어렵지 않습니다.티커가 제대로 표시되지 않는 양식이 표시됩니다.

현재 백그라운드에서 조용히 실행되는 작은 시간 기록 응용 프로그램을 만들고 있습니다. 티커가 다운 될 때마다, 애플리케이션은 사용자에게 마지막 프롬프트 이후에 자신이 한 일을 말하도록 프롬프트합니다. 결국 응용 프로그램에서 스프레드 시트에 데이터를 쓰게됩니다.

내가 지금까지 가지고있는 옵션 중 하나는 사용자가 기본 프롬프트 설정을 사용할지 여부를 사용자가 선택할 수있게합니다 (프롬프트를 놓칠 때마다 다음 프롬프트가 표시 될 때까지 계속 표시됩니다. 사용자가 잠시 동안 컴퓨터를 떠나면 입력 대기중인 화면에 몇 가지 프롬프트가 표시 될 수 있습니다.) 또는 모든 프롬프트를 결합하고자 할 때 (프롬프트가 나타나지 않고 새 메시지가 팝업 될 때마다, 이전 버전은 닫히고 새 버전은 이전 프롬프트 및 새 프롬프트 시간을 포함합니다.

사용자는 프롬프트를 끄기 위해 선택 상자를 선택할 수도 있습니다. 사용자가 프롬프트를 다시 켤 때 프롬프트가 꺼져있는 동안 (사용자가 전체 화면 응용 프로그램을 실행할 때 등) 프롬프트를 표시하면서 사용자가 수행중인 작업을 입력하라는 메시지가 나타납니다.

내 문제는 프롬프트를 생성하려고 할 때 제대로 표시되지 않는다는 것입니다. 나는 그 (것)들을 전혀 교묘히 다룰 수없고 통제의 아무도는 표시하지 않는다. 그들은 기본적으로 빈 형태처럼 보입니다.

여기 티커 사용하여 메시지를 생성하는 내 코드입니다 :

public void ticker(object source, System.Timers.ElapsedEventArgs e) 
    { 
     if (groupMissed) 
     { 
      incrementsMissed += 1; 
      if (incrementsMissed > 1) 
      { 
       IncrementForm form = (IncrementForm)Application.OpenForms["IncrementForm"]; 
       if (form.InvokeRequired) 
       { 
        form.Invoke(new MethodInvoker(delegate { form.Close(); })); 
       } 
      } 
     } 
     else 
     { 
      incrementsMissed = 1; 
     } 

     IncrementForm theIncrementForm = new IncrementForm(this, e.SignalTime); 
     theIncrementForm.Show(); 
     latestIncrement = e.SignalTime; 
    } 

을 그리고 여기에 사용하여 프롬프트 생성하는 내 코드의 "턴을하라는 메시지를 표시"확인란 :

private void chkbxAlerts_Click(object sender, EventArgs e) 
    { 
     if (!chkbxAlerts.Checked) 
     { 
      // Ensures that the time missed is covered and restarts the timer 
      DateTime now; 
      now = DateTime.Now; 
      if ((now - latestIncrement).TotalMinutes >= 1) // Only records time if it is equal to or greater than one minute 
      { 
       // TO-DO: FIX 
       if (groupMissed) 
       { 
        incrementsMissed += 1; 
        if (incrementsMissed > 1) 
        { 
         IncrementForm form = (IncrementForm)Application.OpenForms["IncrementForm"]; 
         if (form.InvokeRequired) 
         { 
          form.Invoke(new MethodInvoker(delegate { form.Close(); })); 
         } 
        } 
       } 
       else 
       { 
        incrementsMissed = 1; 
       } 
       IncrementForm theIncrementForm = new IncrementForm(this, now, latestIncrement); 
       theIncrementForm.Show(); 
       latestIncrement = now; 
      } 
      timer.Enabled = true; 
     } 
     else 
     { 
      // Stops the timer 
      timer.Enabled = false; 
     } 
    } 

당신은 더 이상 설명이 필요한 경우 제발 알려주세요. 어떤 도움을 주셔서 미리 감사드립니다.

+0

매우 잘 형성된 질문입니다. 시세표는 타이머 방식입니까? 타이머가 다른 스레드에서 호출 중입니다 - 거기에서 GUI 양식을 업데이트 할 수 없습니다 (다른 스레드에서 양식을 표시하거나 생성 할 수는 있지만 확실하지는 않습니다). 예, 확실한 또 다른 스레드입니다 – NSGaga

+0

예, 티커는 타이머의 Elapsed 이벤트에 의해 호출됩니다. 내가 말한 GUI 문제를 어떻게 해결할 수 있습니까? – Djentleman

+0

작은 '실행 가능한'예를 만들 수 있습니까? 거기에 내가 추측하고있는 게 더 많아. – NSGaga

답변

2

System.Timers.TimerSynchronizingObject 속성이 도움이되기를 바랍니다. 기본 폼 (또는 타이머가 포함 된 폼)으로 설정하면 GUI 틱에서 타이머 틱 이벤트가 발생합니다.

에는 Elapsed 이벤트에서 발생하는 예외를 삼키는 습관이 있습니다. 진드기 처리기가 예외를 throw하면 결코 표시되지 않습니다. 그것은 더러운 버그 가죽 냄비에요. 따라서 System.Windows.Forms.Timer 또는 System.Threading.Timer을 사용하는 것이 좋습니다. Windows Forms 타이머를 사용하면 경과 이벤트가 GUI 스레드에서 발생합니다. System.Threading.Timer을 사용하는 경우 NSGaga가 답변 한대로 Invoke을 사용해야합니다.

System.Timers.Timer의 사용을 권장하지 않는 이유에 대한 자세한 내용은 Swallowing exceptions is hiding bugs을 참조하십시오.

+0

당신의 솔루션은 잘 작동합니다. 단 하나. System.Windows.Forms.Timer는 System.Timers.ElapsedEventArgs.SignalTime과 동등한 것 같지 않으므로 대신 DateTime.Now를 사용했습니다. 당신이 아직하지 않았다는 것을 알고 싶을지도 모른다고 생각했습니다. – Djentleman

+0

@Djentleman이 하나와 함께 - 나는이 답변을 더 좋아한다 :) – NSGaga

2

내가 볼 수있는 것에서는 100 %가 아니라, 타이머가 별도의 스레드 (타이머 티커 호출에서 오는)에서 창을 생성하고 있다고 생각합니다.

이론적으로는 작동 할 수 있지만 (How to open a form in a thread and force it to stay open을보십시오)
... 주 스레드에 머무르는 것이 훨씬 더 좋습니다. 이 같은

시도 뭔가 ...

yourMainWindow.Invoke(new MethodInvoker(() => 
    { 
     IncrementForm theIncrementForm = new IncrementForm(this, e.SignalTime); 
     theIncrementForm.Show(); 
     latestIncrement = e.SignalTime; 
    })); 

은 ... 그것은 당신의 타이머에서입니다 - 그런 식으로 (내가 볼 수)는 '주 스레드에서'모두를 가지고 일을 훨씬 쉽게한다 너를 위해서.

는이

+0

도움 주셔서 대단히 감사합니다! 비록 내가 당신의 접근법을 사용하지 않고 끝내더라도, 당신은 정말로 더 많은 쓰레드를 이해하는 것을 도왔습니다. 다시 한 번 감사드립니다! – Djentleman