2016-04-22 22 views
0

更新:解決方案已到達並且現在已被接受。由於在這個問題上僞代碼的清晰度,解決方案只需要幾秒鐘。試圖從其他看似「重複」的問題中找出解決方案已經花了很多時間。從我問這個問題的那一刻起,我就有了20分鐘的解決方案。所以它不是重複的,可能是迄今爲止最清楚的。進行跨線程調用以隱藏窗體可視化c#

雖然有人問到過幾個類似的問題,但我仍然無法將它們的工作代碼放在一起。我的主要應用程序不在表單上,​​而是在一個單獨的類中,該類是插件並由主機應用程序執行。

所以雖然它似乎是一個重複的問題,它不是。請繼續閱讀。

我有我的主要課程做東西。然後我有一個向用戶顯示信息的表單。當用戶離開應用程序時(主機應用程序失去焦點),我需要隱藏此表單。

我使用的是非常有限的API,因此我在主機應用程序觸發的唯一方法中處理事件。

我創建了一個計時器,每隔100ms觸發一次,並檢查用戶是否有焦點的應用程序。如果不是,則將命令發送到表單以隱藏自身。

此方法的原因是因爲宿主應用程序失去焦點只是我需要隱藏窗體的許多場景之一,我需要通過相同的確切方法來引導所有這些場景。

所有的類的其餘部分中工作(該Hide()方法是從應用程序的其餘 稱爲沒有問題的。但是,當計時器調用Hide()方法,因爲計時器是在不同的線程它不工作,當它觸發時,呼叫成爲一個跨線程調用

非常具體的問題是,我需要一個確切的示例代碼如何使這個調用從計時器事件處理程序到窗體的Hide()方法線程安全與Invoke

謝謝。

這是定時器:

private void Controllel_Opened(object sender, EventArgs e) 
{ 
    myTimer.Elapsed += new System.Timers.ElapsedEventHandler(DisplayTimeEvent); 
    myTimer.Interval = 50; 
    myTimer.Start(); 
} 

public static System.Timers.Timer myTimer = new System.Timers.Timer(); 
// This method checks different scenarios when the tool tip should be hidden and calls the hiding method 
public static void DisplayTimeEvent(object source, System.Timers.ElapsedEventArgs e) 
{ 
    FormHandler.Hide(); 
} 

那麼 「FormHandler」 類:

public static class FormHandler 
{ 
    private static Form1 frm1 = new Form1(); 

    public delegate void Form1HideEventHandler(); 
    public static event Form1HideEventHandler Form1Hide; 

    public static void Hide() 
    { 
     if (Form1Hide != null) 
     { 
      Form1Hide(); 
     } 

    } 
} 

然後窗體代碼:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     FormHandler.Form1Hide += FormHandler_Form1Hide; 
    } 

    private void FormHandler_Form1Hide() 
    { 
     Hide(); 
    } 
} 

我想獲得與確切的代碼的解決方案如果可能的話。謝謝。

+3

找到一個更好的重複:http://stackoverflow.com/questions/1523878/getting-cross-thread-operation-not-valid – Rob

+0

@Rob - 謝謝。這可能會導致我找到解決方案。但是,使用上述僞代碼的確切代碼是什麼? – ib11

回答

2
private void FormHandler_Form1Hide() 
{ 
    if (InvokeRequired) 
    { 
     this.Invoke(new Action(() => { FormHandler_Form1Hide(); })); 
    } 
    else 
    { 
     Hide(); 
    } 
} 
+0

非常好!謝謝。是的,這是**完美的**與您的編輯添加'else'部分。當我申請你的樣品時,我已經有了這個。 – ib11

+2

僅用於* DRY *,我更喜歡在InvokeRequired部分調用self而不是重複下面的代碼...例如:if(InvokeRequired){this.Invoke(()=> FormHandler_Form1Hide()) ;返回; }'那麼萬一函數變長,你不必重複你的代碼 – Jcl

+0

@Jcl好的建議 - 我現在更新。謝謝! – Rob

0

您需要改用System.Windows.Forms.Timer。這將調用回調度器線程。

+0

這就是問題所在,我需要從表單外部調用表單。原因是因爲宿主應用程序失去焦點只是我需要隱藏表單的許多場景之一,我需要通過相同的確切方法來引導所有這些場景。 – ib11

+0

是的,但是如果你使用那個定時器,它會重新回到UI線程。方法並不重要,重要的是線程。 – briantyler