2011-02-18 34 views
2

我想從另一個線程更改菜單項。我可以在其他控件上使用InvokeRequired/Invoke,但由於菜單項不是控件,因此難以實現相同的功能。從另一個線程啓用/禁用菜單項

對於其它控件,我這樣做:

private delegate void SetControlEnableHandler(object sender, Boolean bValue); 

private void SetControlEnabled(object sender, Boolean bValue) 
{ 
    Control control = (Control)sender; 
    if (control.InvokeRequired) 
    control.Invoke(
     new SetControlEnableHandler(SetControlEnabled), 
     new object[] { sender, bValue } 
    ); 
    else 
    control.Enabled = bValue; 
} 

從工作線程我簡單的調用:

this.SetControlEnabled(btnPress, true); 

和它的工作。

任何人都可以幫我在這裏的菜單項?

謝謝你, -Bhaskar

+2

只是一個說明,如果你的操作完成後直接通知UI線程會不會更好,那麼UI線程將負責更改控件屬性?這也可以更好地隔離用戶界面中的背景/後端/工作邏輯。 – 2011-02-18 14:43:57

回答

4

菜單項不是控制,而是託管的MenuStrip形式。因此,如果在正確的線程中調用該窗體中的方法,則可以修改該菜單項。

所以,

private void EnableMenuItem(ToolStripMenuItem item, bool enabled) 
    { 
     this.BeginInvoke(new MethodInvoker(delegate() 
     { 
      item.Enabled = enabled; 
     } 
     )); 
    } 

可能會做你想要什麼。請注意,使用匿名方法保存必須定義(可能)不會在其他地方使用的委託。另外,另一方面,您正在使用的Control.Invoke的重載具有用params []標記的第二個參數 - 這是c#如何實現可變數量的參數。你不需要建立一個對象數組,只需要添加你需要的對象作爲參數。

例如,

control.Invoke(new SetControlEnableHandler(SetControlEnabled), new object[] { sender, bValue }); 

可以寫成

control.Invoke(new SetControlEnableHandler(SetControlEnabled), sender, bValue); 

這是好得多,我相信你會同意。