I will start to write a series of blog post that will answer the most common questions about Visual Studio extensibility and DSLs.
Lets go with the first one: How do I keep track of selection in a DSL designer
Scenario
Let's say that we want to synchronize the DSL designer with the DSL model explorer. Somehow we need to keep track the selections in the diagram and push them back to model explorer tool window. The focus of this How do I tackles this scenario.
Interfaces and classes needed
Code snippet
Hard way:
publicclassMonitorSelection : IVsSelectionEvents, IDisposable
{
privatebool isDisposed;
privateuint selectionCookie;
privateIVsMonitorSelection monitorSelection;
public MonitorSelection(IServiceProvider serviceProvider)
{
this.monitorSelection = serviceProvider.GetService(typeof(SVsShellMonitorSelection)) asIVsMonitorSelection;
this.monitorSelection.AdviseSelectionEvents(this, outthis.selectionCookie);
}
intIVsSelectionEvents.OnCmdUIContextChanged(uint dwCmdUICookie, int fActive)
{
returnVSConstants.S_OK;
}
intIVsSelectionEvents.OnElementValueChanged(uint elementid, object varValueOld, object varValueNew)
{
returnVSConstants.S_OK;
}
intIVsSelectionEvents.OnSelectionChanged(IVsHierarchy pHierOld, uint itemidOld, IVsMultiItemSelect pMISOld, ISelectionContainer pSCOld, IVsHierarchy pHierNew, uint itemidNew, IVsMultiItemSelect pMISNew, ISelectionContainer pSCNew)
{
var view = pSCNew asModelingDocView;
if(view != null)
{
var pel = view.PrimarySelection asPresentationElement;
if(pel != null && !(pel isDiagram))
{
//TODO: Access the model element via pel.ModelElement property
}
}
returnVSConstants.S_OK;
}
publicvoid Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
privatevoid Dispose(bool disposing)
{
if(!this.isDisposed)
{
if(disposing && (this.selectionCookie != 0))
{
this.monitorSelection.UnadviseSelectionEvents(this.selectionCookie);
this.selectionCookie = 0;
}
this.isDisposed = true;
}
}
}
Easy way:
IMonitorSelectionService monitorSelectionService = serviceProvider.GetService(typeof(IMonitorSelectionService)) asIMonitorSelectionService;
var view = monitorSelectionService.CurrentDocumentView asModelingDocView;
if(view != null)
{
var pel = view.PrimarySelection asPresentationElement;
if(pel != null && !(pel isDiagram))
{
//TODO: Access the model element via pel.ModelElement property
}
}
Assemblies needed
- Microsoft.VisualStudio.Shell.Interop
- Microsoft.VisualStudio.Modeling.Sdk.Shell
- Microsoft.VisualStudio.Modeling.Sdk.Diagrams
Stay tuned,
Pablo