Hello,
Is there a way to dynamically create shapes. I would like to create a ModelElement on loading the .xyz designer. Is it possible to create multiple shapes / connectors on drag and drop of an element from the toolbox. In the ElementAdded method can I create shapes - do we have a method CreateModelElement() or API's to create model elements
Thanks,
Julian Jewel

Dynamically create shapes
Tyrion
Thanks! That was very helpful. How do you create a Connection (in this example - Association) I have EntityA and EntityB. Should I use CreateAssociation() with the roletypes or is there a method like Connect(EntityA, EntityB);
Or can I add the relationship into the model and automatically that would update the designer, showing the connection between EntityB->EntityA
Thanks,
Julian Jewel
UZone
Thanks
Tom
JayaK
My addition is under /* Experimental code */.
ViewFixupRules are responsible for making sure that the displayed diagram keeps in step with the underlying model. So when you create something in the model, it automatically appears in the diagram. (Warning: this may change in future, when diagrams can be partial views of a model.)
So this code is inserted into the rule that "fixes up" the diagram when a new link of a specific type is created. It creates a new model element, and initialises it with some attributes - most importantly, a name. (The attributes are of course as defined in the dsldm file; apart from the name attribute, which all elements inherit from NamedElement defined in Core.dsldm.) It then adds the new element to the root Architecture's list of Components: in the dslDD file, you can see that Architecture is the root of any diagram, and its Components list (ie the relation ArchitectureHasComponents) is the set of things that appear on the diagram.
Many operations require "store" as a parameter; you can mostly get that from any convenient element that is to hand.
/// <summary> /// Add a DependencyLink connector when its underlying relationship is created /// </summary>
[
RuleOn(typeof(ComponentIsDependentOn), FireTime = TimeToFire.TopLevelCommit, Priority = DiagramFixupConstants.AddShapeRulePriority)] internal sealed class ComponentIsDependentOnAddRule : AddRule{
/// <summary> /// Called when a ComponentIsDependentOn relationship is created. /// </summary> /// <param name="e">Argument to event</param> public override void ElementAdded(ElementAddedEventArgs e){
ComponentIsDependentOn relationship = e.ModelElement as ComponentIsDependentOn; if (relationship != null){
IList roots = relationship.Store.ElementDirectory.GetElements(Architecture.MetaClassGuid); if (roots.Count == 1){
Architecture root = roots[0] as Architecture; if (root != null){
Microsoft.VisualStudio.Modeling.Diagrams.
Diagram.FixUpDiagram(root, relationship);
/* Experimental code */ // Grab store from any convenient element Store store = relationship.Store; // Create element and assign its attributes, especially Name Framework extra = Framework.CreateFramework(store);extra.Name =
"ExtraFramework";extra.MajorVersion = 1;
extra.MinorVersion = 2;
extra.ServicePack = 10;
// Make new element part of the model.extra.Architecture = root;
/* End experiment */// the above is equivalent to: root.Components.Add(extra);
}
}
}
}
}
To try this code after replacing the relevant function in ViewFixupRules.cs, hit F5 (*don't* do Transform All Templates!); open Empty.xyz in the resulting designer; drag a Framework and an OperatingSystem onto the drawing surface; and connect them with a Dependency link. Notice that this last action creates a new Framework.
happi.quan
You add some code into ViewFixup.cs -- actually, you'd put it in the dslddt file -- that looks like this:
#region
Structural Rules[
RuleOn(typeof(ArchitectureHasComponents), FireTime = TimeToFire.TopLevelCommit, Priority = DiagramFixupConstants.AddShapeRulePriority)] public sealed class ArchitectureHasComponentsAddRule : AddRule{
/// <summary>
/// Called when a ArchitectureHasComponents association is created.
/// </summary>
/// <param name="e">Argument to event</param>
public override void ElementAdded(ElementAddedEventArgs e)
{
ArchitectureHasComponents s = e.ModelElement as ArchitectureHasComponents;
if (s.Components != null && s.Architecture != null)
{
Microsoft.VisualStudio.Modeling.Diagrams.Diagram.FixUpDiagram(s.Architecture, s.Components);
/* Experimental code */
// This code adds and connects an extra OperatingSystem node whenever you create a Framework.
if (s.Components is Framework)
// Don't be fooled by the plural! Although the rolename is Component*s*, each individual link only has one ModelElement at the end of it.
{
// Grab store from any convenient element
Store store = s.Store;
// Create extra element and assign its attributes, especially Name
CompanyName.ProjectName.Language34.DomainModel.OperatingSystem extra =
// fully qualified name here because "OperatingSystem" is also the name of some other type
CompanyName.ProjectName.Language34.DomainModel.OperatingSystem.CreateOperatingSystem(store);
extra.Name = "ExtraOS";
extra.MajorVersion = 1;
extra.MinorVersion = 2;
extra.ServicePack = 10;
// Add the new element under the root of the model
extra.Architecture = s.Architecture;
// Connect the new element to the Framework using a relation defined in the DM
extra.DependentOn = s.Components;
}
/* End experiment */
}
}
}
#endregion
Once again, the statutory warning that we're working with a Preview release here, so nothing is yet guaranteed to stay the same.
Q. Why don't we use the OnCreated() handler on the Framework, like we did with Architecture above
A. 'Cos it don't work too well. The advantage of the rules is that they fire after everything is in a consistent state. In the other case, it just happens to be OK and easier; but in general, it's best to create rules to handle changes.
Aton A
Official help:
http://msdn2.microsoft.com/en-us/library/bb126619(VS.80).aspx
An example from this forum:
http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=799447&SiteID=1
Here, Duncan explains an advanced usage:
http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=1108399&SiteID=1
Cheers,
Gokhan
CrioGreen
(Passenger)
|-----Rides-1>|*|-----(Car)
then you can do things like:
aPassenger.Rides = aCar;
If your association is a multiple in the direction you're interested in, for example:
(Person)
|----------Likes--*>|*|-----(Thing)
then you can write:
aPerson.Likes.Add(aThing);
You can alternatively set up the links in reverse - for example,
aCar.RiddenBy.Add(aPassenger)
is the same as the line above, presuming "RiddenBy" is the reverse role of "Rides". (To see the name of the reverse role in the DM editor, click on the rectangular role symbol -- it's a bit difficult sometimes unless you zoom in a bit -- and look at the name in the properties grid.)
abbasshaikh
You can add something like this in a separate file, or append it to DomainModel\DomainModelExtras.dsldmt. This example was added to a solution initially created from the Simple Architecture Chart prototype; Architecture is the name of the language root class, and Computer is one of the concept classes.
public partial class Architecture
{
///<summary>Invoked once when a new model is created.
/// This class is the root of the language.
///</summary>
public override void OnInitialized()
{
base.OnInitialized();
// Create an object to be automatically added to the new model.
Computer primary = Computer.CreateComputer(this.Store);
// Set its attributes (as defined in the .dslDM, plus Name)
primary.Name = "PrimaryComputer";
primary.HardDiskSize = 50;
primary.HardDiskSizeUnit = StorageSize.GB;
primary.MemorySize = 500;
primary.MemorySizeUnit = StorageSize.MB;
// link the new item to the root of the model
primary.Architecture = this;
}
}
This will fire only when the model is initially created - not when it's loaded after saving. If you really want to create a new thing every time the model is loaded, override OnCreated() instead.
BTW, OnCreated and OnInitialized are often not too useful -- they don't fire at the right times to do the right things on the diagram. The good thing about the rule-based approach is that the rules fire after all the changes in the model have completed.