2014-02-26 49 views
1

我在Menu Controller中實現了DynamicItemStart按鈕。我在Visual Studio啓動時加載此按鈕的動態項目。一切正確加載,所以初始化方法被稱爲我看到這個動態按鈕中的所有新項目。包完全加載後,我想添加更多的項目到這個動態按鈕,但由於包已經加載,初始化方法不會再次被調用,我看不到這個動態按鈕中的新項目。我只看到VS開始時加載的那些。如何在vsix包中使用DynamicItemStart時更新Visual Studio UI

是否有任何方法可以強制更新此動態按鈕,以便顯示新項目?我希望能夠在添加更多項目但在Initialize方法之外後更新VS UI。 我做的實現非常相似,一個表現出對這個MSDN例如:

http://msdn.microsoft.com/en-us/library/bb166492.aspx

有誰知道了該UI的更新可以通過需求來完成?

任何提示,非常感謝。

+0

您可以使用'IVsUIShell'服務的'UpdateUI'方法。 – Matze

+0

您是否確定動態啓動命令的id足夠大,以便它不與vsct文件中的其他已定義命令重疊? – Matze

+0

是的,它足夠大,所以它不重疊。 – gab

回答

2

我終於得到了這個工作。主要的是OleMenuCommand派生類的實現,它實現了一個帶有Predicate的新構造函數。該謂詞用於檢查新的命令是否在DynamicItemStart按鈕內匹配。

public class DynamicItemMenuCommand : OleMenuCommand 
{ 
private Predicate<int> matches; 
public DynamicItemMenuCommand(CommandID rootId, Predicate<int> matches, EventHandler invokeHandler, EventHandler beforeQueryStatusHandler) 
    : base(invokeHandler, null, beforeQueryStatusHandler, rootId) 
{ 
    if (matches == null) 
    { 
    throw new ArgumentNullException("Matches predicate cannot be null."); 
    } 

    this.matches = matches; 
} 


public override bool DynamicItemMatch(int cmdId) 
{ 
    if (this.matches(cmdId)) 
    { 
    this.MatchedCommandId = cmdId; 
    return true; 
    } 

    this.MatchedCommandId = 0; 
    return false;  
} 

}

上面類應添加於執行時間的命令時使用。下面是一個創建命令

public class ListMenu 
{ 
private int _baselistID = (int)PkgCmdIDList.cmdidMRUList;  
private List<IVsDataExplorerConnection> _connectionsList; 


public ListMenu(ref OleMenuCommandService mcs) 
{    
    InitMRUMenu(ref mcs); 
}  

internal void InitMRUMenu(ref OleMenuCommandService mcs) 
{    
    if (mcs != null) 
    {    
    //_baselistID has the guid value of the DynamicStartItem 
    CommandID dynamicItemRootId = new CommandID(GuidList.guidIDEToolbarCmdSet, _baselistID); 
    DynamicItemMenuCommand dynamicMenuCommand = new DynamicItemMenuCommand(dynamicItemRootId,  isValidDynamicItem, OnInvokedDynamicItem, OnBeforeQueryStatusDynamicItem); 
      mcs.AddCommand(dynamicMenuCommand);     
    } 
} 

private bool IsValidDynamicItem(int commandId)  
{  
    return ((commandId - _baselistID) < connectionsCount); // here is the place to put the criteria to add a new command to the dynamic button 
} 


private void OnInvokedDynamicItem(object sender, EventArgs args) 
{ 
    DynamicItemMenuCommand invokedCommand = (DynamicItemMenuCommand)sender;  

    if (null != invokedCommand) 
    { 
    ..... 
    } 
} 

private void OnBeforeQueryStatusDynamicItem(object sender, EventArgs args) 
{ 
    DynamicItemMenuCommand matchedCommand = (DynamicItemMenuCommand)sender;   

    bool isRootItem = (matchedCommand.MatchedCommandId == 0); 
    matchedCommand.Enabled = true; 
    matchedCommand.Visible = true; 
    int indexForDisplay = (isRootItem ? 0 : (matchedCommand.MatchedCommandId - _baselistID)); 
    matchedCommand.Text = "Text for the command"; 
    matchedCommand.MatchedCommandId = 0; 
} 

}

我不得不審查大量的文檔資料,因爲它不是很清楚如何命令可在執行時添加的代碼。所以我希望這可以節省一些時間,無論誰需要執行類似的任何事情。

+0

由於實際問題與動態菜單項有關,因此您可以更新問題標題... – Matze

+0

@Matze - 感謝您的建議。我改寫了標題。希望更清楚這種方式。 – gab

1

對我來說缺少的一塊是搞清楚如何控制新項目的添加。

我花了一些時間才發現匹配謂詞(示例中的IsValidDynamicItem方法)控制添加了多少項 - 只要它返回true,就會調用OnBeforeQueryStatusDynamicItem並可以設置細節(Enabled/Visible/Checked/Text等)匹配項添加到菜單中。

相關問題