モデルを移動する
所有関係にあるモデルを移動する方法について説明します。
指定位置に移動する
自モデルの親モデルを指定のモデルに変更する場合は、IModel
オブジェクトのMoveTo
メソッドを用います。新しい親モデル、移動先のフィールドの名前、移動方向と基準位置を指定します。
public void MoveTo(ICommandContext c, ICommandParams p)
{
// 移動対象のモデルを取得します
IModel model = c.App.Workspace.CurrentModel;
// 新しい親モデルを取得します
// モデルパスを指定してモデルを取得する場合
IModel newOwner = model.OwnerProject.GetModelByPath("サンプルプロジェクト/ユースケースモデル");
// 移動対象のモデルを新しい親モデルの子要素として移動します
// 新しい親モデルの"Actors"フィールドの末尾に移動する場合
model.MoveTo(newOwner, "Actors", "last", 0);
}
移動先の親モデルとフィールドに現在と同じものを指定すると、自モデルの順序を 変更することができます。
public void ChangeOrder(ICommandContext c, ICommandParams p)
{
// 移動対象のモデルを取得します
IModel model = c.App.Workspace.CurrentModel;
// 現在の親モデルと所有フィールドを指定して、移動対象のモデルを移動します
// この場合、移動対象モデルのフィールド内の順序を変更します
// モデルを先頭に移動する場合
model.MoveTo(model.Owner, model.GetOwnerField().Name, "first", 0);
}
例えば、所有フィールド内のモデルを名前順に並べ替える場合は次のように定義します。
public void SortByName(ICommandContext c, ICommandParams p)
{
// 親モデルと所有フィールドを取得します
IModel owner = c.App.Workspace.CurrentModel;
IField field = owner.Metaclass.Fields["所有フィールド名"];
// 並び替え対象のモデルを取得します
List<IModel> targetModels = owner.GetFieldValues(field.Name).ToList();
// モデルを名前順に並び替えます
targetModels.Sort((model1, model2) => String.CompareOrdinal(model1.Name, model2.Name));
// モデルの移動を利用して、モデルの順序を変更します
foreach(var model in targetModels)
{
model.MoveTo(owner, field.Name, "last", 0);
}
}
次のような拡張メソッドを定義しておくと、フィールド内のモデルを任意の順序で並べ替えることができます。
public static class IModelExtension
{
public static void Sort(this IModel owner, IField field, IComparer<IModel> comparer)
{
// 並び替え対象のモデルを取得します
List<IModel> targetModels = owner.GetFieldValues(field.Name).ToList();
// モデルを並び替えます
targetModels.Sort(comparer);
// 移動先の親モデルとフィールドに現在と同じものを指定して、モデルの順序を変更します
foreach (IModel model in targetModels)
{
model.MoveTo(owner, field.Name, "last", 0);
}
}
}
先の名前順の並べ替えを拡張メソッドを用いて実現すると次のようになります。
public void SortByNameUsingExtensionMethod(ICommandContext c, ICommandParams p)
{
// 親モデルと所有フィールドを取得します
IModel owner = c.App.Workspace.CurrentModel;
IField field = owner.Metaclass.Fields["所有フィールド名"];
// モデルの並び替えを行います
// 並び替えの順序は実装した ModelComparer に従います
owner.Sort(field, new ModelComparer());
}
// IModel の順序を決定するクラス
public class ModelComparer : IComparer<IModel>
{
public int Compare(IModel model1, IModel model2)
{
// 名前順に並び替 えます
return String.CompareOrdinal(model1?.Name, model2?.Name);
}
}
IModel
オブジェクトのMoveTo
メソッドの第3引数、第4引数には、それぞれ移動先における追加方向、追加基準位置を指定します。
追加方向(direction):
文字列で方向を指定します。指定できる値は以下のいずれかです。
指定できる値 | 追加方向 |
---|---|
first | 先頭 |
last | 末尾 |
before | 前 |
after | 後 |
追加基準位置(index):
先頭位置を0とするインデックスを整数で指定します。追加方向の指定値によって、追加位置が変わります。
追加方向の値 | 追加位置 |
---|---|
first | インデックスの値に関係なく先頭 |
last | インデックスの値に関係なく末尾 |
before | 指定したインデックス位置 |
after | 指定したインデックス位置の次の位置 |
自分の子要素として移動する
指定のモデルの親モデルを自モデルに変更する場合は、IModel
オブジェクトのTake
メソッドを用います。
public void TakeModel(ICommandContext c, ICommandParams p)
{
// 移動先の親モデルを取得します
IModel model = c.App.Workspace.CurrentModel;
// 移動対象のモデルを取得します
// モデルパスを指定してモデルを取得する場合
IModel target = model.OwnerProject.GetModelByPath("サンプルプロジェクト/システム要件/非機能要件");
// 移動先の親モデルの子要素として移動対象のモデルを移動します
// 移動先の親モデルの"SubRequirements"フィールドの末尾に移動する場合
model.Take("SubRequirements", target, "last", 0);
}
移動方向と基準位置の詳細は、IModel
オブジェクトのMoveTo
メソッドと同様で す。