You can embed a DSL diagram in a Windows Control, which appears in the Visual Studio window.
Embedding a Diagram
To embed a DSL diagram in a Windows Control
- Add a new User Control file to the DslPackage project. 
- Add a Panel control to the User Control. This panel will contain the DSL Diagram. - Add other controls that you require. - Set the Anchor properties of the controls. 
- In Solution Explorer, right-click the user control file and click View Code. Add this constructor and variable to the code: - internal UserControl1(MyDSLDocView docView, Control content) : this() { panel1.Controls.Add(content); this.docView = docView; } private MyDSLDSLDocView docView;
- Add a new file to the DslPackage project, with the following content: - using System.Windows.Forms; namespace Company.MyDSL { partial class MyDSLDocView { private UserControl1 container; public override IWin32Window Window { get { if (container == null) { // Put our own form inside the DSL window: container = new UserControl1(this, (Control)base.Window); } return container; } } } }
- To test the DSL, press F5 and open a sample model file. The diagram appears inside the control. The toolbox and other features work normally. 
Updating the Form using Store Events
- In the form designer, add a ListBox named listBox1. This will display a list of the elements in the model. It will be kept in synchronism with the model using store events. For more information, see Event Handlers Propagate Changes Outside the Model. 
- In the custom code file, override further methods to the DocView class: - partial class MyDSLDocView { /// <summary> /// Register store event listeners. /// This method is called when the model and diagram /// have completed loading. /// </summary> protected override bool LoadView() { bool result = base.LoadView(); Store store = this.DocData.Store; EventManagerDirectory emd = store.EventManagerDirectory; DomainClassInfo componentClass = store.DomainDataDirectory.FindDomainClass(typeof(ExampleElement)); emd.ElementAdded.Add(componentClass, new EventHandler<ElementAddedEventArgs>(AddElement)); emd.ElementDeleted.Add(componentClass, new EventHandler<ElementDeletedEventArgs>(RemoveElement)); // Do the initial parts list: container.SetUpFormFromModel(); return result; } /// <summary> /// Listener method called on creation of each instance of /// the ExampleElement class or its subclasses. /// </summary> private void AddElement(object sender, ElementAddedEventArgs e) { container.Add(e.ModelElement as ExampleElement); } /// <summary> /// Listener method called after deletion of each instance of /// the ExampleElement class or its subclasses. /// </summary> private void RemoveElement(object sender, ElementDeletedEventArgs e) { container.Remove(e.ModelElement as ExampleElement); }
- In the code behind the user control, insert methods to listen for elements added and removed: - public partial class UserControl1 : UserControl { ... private ExampleModel modelRoot; internal void Add(ExampleElement e) { UpdatePartsList(); } internal void Remove(ExampleElement e) { UpdatePartsList(); } internal void SetUpFormFromModel() { modelRoot = this.docView.CurrentDiagram.ModelElement as ExampleModel; UpdatePartsList(); } private void UpdatePartsList() { StringBuilder builder = new StringBuilder(); listBox1.Items.Clear(); foreach (ExampleElement c in modelRoot.Elements) { listBox1.Items.Add(c.Name); } }
- To test the DSL, press F5 and in the experimental instance of Visual Studio, open a sample model file. - Notice that the list box shows a list of the elements in the model, and that it is correct after any addition or deletion, and after Undo and Redo. 
See Also
Concepts
Navigating and Updating a Model in Program Code
Other Resources
Writing Code to Customise a Domain-Specific Language
Change History
| Date | History | Reason | 
|---|---|---|
| March 2011 | Separated from parent topic. | Information enhancement. |