Skip to main content

Move a model

Explains how to move models that are owned by another model.

Move to a specified position

To change the parent model of your model to a specified model, use the MoveTo method of the IModel object. Specify the new parent model, the name of the destination field, the direction of movement, and the base position.

public void MoveTo(ICommandContext c, ICommandParams p) 
{
//Get the model to be moved
IModel model = c.App.Workspace.CurrentModel;
//Get the new parent model
//When getting a model by specifying the model path
IModel newOwner = model.OwnerProject.GetModelByPath("Sample Project/Use Case Model");
//Move the model to be moved as a child element of the new parent model
//When moving to the end of the "Actors" field of the new parent model
model.MoveTo(newOwner, "Actors", "last", 0);
}

You can change the order of your own models by specifying the same parent model and field as the current one for the destination.

public void ChangeOrder(ICommandContext c, ICommandParams p) 
{
//Get the model to be moved
IModel model = c.App.Workspace.CurrentModel;

//Specify the current parent model and the owned field to move the model to be moved
//In this case, change the order in the field of the model to be moved
//To move the model to the top
model.MoveTo(model.Owner, model.GetOwnerField().Name, "first", 0);
}

For example, to sort the models in the owned field by name, define it as follows.

public void SortByName(ICommandContext c, ICommandParams p) 
{
//Get the parent model and the owned field
IModel owner = c.App.Workspace.CurrentModel;
IField field = owner.Metaclass.Fields["OwnedFieldName"];

//Get the models to sort
List<IModel> targetModels = owner.GetFieldValues(field.Name).ToList();

//Sort the models by name
targetModels.Sort((model1, model2) => String.CompareOrdinal(model1.Name, model2.Name));

//Use model movement to change the order of the models
foreach(var model in targetModels)
{
model.MoveTo(owner, field.Name, "last", 0);
}
}

You can sort the models in a field in any order by defining an extension method like the following.

public static class IModelExtension 
{
public static void Sort(this IModel owner, IField field, IComparer<IModel> comparer)
{
//Get the models to be sorted
List<IModel> targetModels = owner.GetFieldValues(field.Name).ToList();

//Sort the models
targetModels.Sort(comparer);

//Change the order of the models by specifying the parent model and field to be moved to the same as the current one
foreach (IModel model in targetModels)
{
model.MoveTo(owner, field.Name, "last", 0);
}
}
}

The following is the sorting by name that was mentioned above, achieved using the extension method.

public void SortByNameUsingExtensionMethod(ICommandContext c, ICommandParams p) 
{
//Get parent model and owned field
IModel owner = c.App.Workspace.CurrentModel;
IField field = owner.Metaclass.Fields["OwnedFieldName"];

//Sort the models
//The sorting order follows the implemented ModelComparer
owner.Sort(field, new ModelComparer());
}

//Class that determines the order of IModel
public class ModelComparer : IComparer<IModel>
{
public int Compare(IModel model1, IModel model2)
{
//Sort by name
return String.CompareOrdinal(model1?.Name, model2?.Name);
}
}

The third and fourth arguments of the MoveTo method of the IModel object specify the direction of addition and the base position of addition at the destination, respectively.

Direction of addition:
Specify the direction with a string. You can specify one of the following values.

Specifiable values ​​Direction of addition
firstBeginning
lastEnd
beforeBefore
afterAfter

Base position of addition:
Specify an integer index with the first position being 0. The position of addition changes depending on the value specified for the direction of addition.

Add direction valueAdd position
firstThe beginning regardless of the index value
lastThe end regardless of the index value
beforeThe specified index position
afterThe next position after the specified index position

Move as a child element of itself

To change the parent model of a specified model to your own model, use the Take method of the IModel object.

public void TakeModel(ICommandContext c, ICommandParams p) 
{
//Get the parent model of the destination
IModel model = c.App.Workspace.CurrentModel;

//Get the model to be moved
//When getting the model by specifying the model path
IModel target = model.OwnerProject.GetModelByPath("Sample Project/System Requirements/Non-Functional Requirements");

//Move the model to be moved as a child element of the destination parent model
//When moving to the end of the "SubRequirements" field of the destination parent model
model.Take("SubRequirements", target, "last", 0);
}

Details of the movement direction and reference position are the same as the MoveTo method of the IModel object.