[Updated: changed "ContainerControl" to "MyContainerControl" - ContainerControl gets confused with System.Windows.Forms.ContainerControl.]
I want to embed my DSL Diagram inside some standard Windows buttons and menus etc - though with all of that still inside a VS window. This turns out to be pretty easy.
Here's how:
- Make a User Control inside your DslPackage project. (In Solution Explorer, right click on DslPackage > Add > User Control.)
- If you want to put it inside a Custom folder inside the DslPackage project, make sure the namespace doesn't get ".Custom" at the end of it. I cheated and created the file in the main package then moved it into the folder. If you create it directly in the Custom folder, you have to open both of the generated code files to fix the namespaces.
- Using the usual WinForms editor, add your buttons and menus and stuff, and a Panel to put the DSL window into.
- Add a public property into the User Control to let you set the content of the Panel.
- While you're there, add a property to let you keep a reference to a DiagramDocView.
The extra code looks like this:
[code]
namespace
Fabrikam.WinformDSL1
{
publicpartialclass MyContainerControl :UserControl
{
public MyContainerControl()
{
InitializeComponent();
}
// Start of my extras
privateDiagramDocView docView;
public MyContainerControl(DiagramDocView
docView, Control content) :this()
{
this.docView = docView;
panel1.Controls.Add(content);
}
[/code]
- Now add a partial class definition for your DocView class, and override Window. It should return your ContainerControl. If the control doesn't exist yet, it should create it and put the base.Window inside it.
[code]
namespace
Fabrikam.WinformDSL1
{
internalpartialclassWinformDSL1DocView
{
private MyContainerControl container;
///<summary>
/// Return a User Control instead of the DSL window.
/// The user control will contain the DSL window.
///</summary>
publicoverride System.Windows.Forms.IWin32Window Window
{
get
{
if (container ==null)
{
// Put the normal DSL Window inside our control
container =new MyContainerControl(this, (System.Windows.Forms.Control)base.Window);
}
return container;
}
}
}
}
[/code]
At this point, the DSL should display nicely inside the form.
Now you'll probably want to access the Store contents from buttons etc on the form:
[code]
privatevoid button1_Click(object sender,EventArgs e)
{
// Some of this should probably be separated out to the DSL package...
ExampleModel modelRoot =this.docView.CurrentDiagram.ModelElement
asExampleModel;
foreach (ExampleElement elementin modelRoot.Elements)
{
listBox1.Items.Add(element.Name);
}
}
[/code]