방법: 끌어서 놓기 처리기 추가
사용자가 항목에 다이어그램 또는 다른 다이어그램의 다른 부분에서 끌 수 있도록를 DSL 드래그 앤 드롭 이벤트에 대해 처리기를 추가할 수 있습니다 Visual Studio.이벤트를 두 번 클릭에 대 한 처리기를 추가할 수도 있습니다.두 번 클릭 및 끌어서 놓기 처리기로 알려져 있습니다 제스처 처리기.
이 항목에서 발생 하는 드래그 앤 드롭 제스처 다른 다이어그램에 설명 합니다.이동 및 복사 이벤트에 대해 단일 다이어그램 내에서 서브 클래스 정의의 대 안으로 고려 ElementOperations.자세한 내용은 방법: 프로그램 복사 및 붙여넣기 동작 - 리디렉션를 참조하십시오.DSL 정의 사용자 지정할 수도 있습니다.
항목 내용
처음 두 섹션이 제스처 처리기를 정의 하는 다른 방법에 설명 합니다.
제스처 처리기를 재정의 하는 ShapeElement 메서드에 의해 정의.OnDragDropOnDoubleClick, OnDragOver, 및 다른 메서드를 재정의할 수 있습니다.
MEF를 사용 하 여 동작 처리기 정의.타사 개발자를 DSL 자체 처리기를 정의할 수 있도록이 메서드를 사용 합니다.DSL을 설치한 타사 확장 프로그램을 설치 하려면 사용자가 선택할 수 있습니다.
끌어 온된 항목을 디코딩하는 방법.창 또는 바탕 화면에서 뿐 DSL에서 요소를 끌 수 있습니다.
원래 하는 항목을 끌어.끌어 온된 항목 DSL 요소인 경우 원본 모델을 열고 액세스할 수 있습니다.
마우스를 사용 하 여: 구획 항목 끌기.이 샘플에서는 가로채 마우스 동작에 대 한 셰이프 필드에는 하위 수준 처리기를 보여 줍니다.예제 항목에는 마우스를 드래그 하 여 순서를 변경할 수가 있습니다.
ShapeElement 메서드를 재정의 하 여 동작 처리기를 정의 합니다.
DSL 프로젝트에 새 코드 파일을 추가 합니다.제스처 처리기에서는 일반적으로 적어도 있어야 using 문의 하십시오.
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
using System.Linq;
새 파일을 끌기 작업에 응답 해야 하는 도형 또는 다이어그램 클래스의 partial 클래스를 정의 합니다.다음 메서드를 재정의 합니다.
OnDragOver-이 메서드는 끌기 작업 도중 마우스 포인터가 도형에 진입 하면 호출 됩니다.메서드를 사용자가 드래그 하는 항목을 검사 하 고 사용자가 항목이이 셰이프를 삭제할 수 있는지 여부를 나타내는 효과 속성을 설정 해야 합니다.이 셰이프 위에 고도 결정 하는 동안 커서 모양이 효과 속성 결정 여부 OnDragDrop() 마우스 단추를 놓을 때 호출 됩니다.
partial class MyShape // MyShape generated from DSL Definition. { public override void OnDragOver(DiagramDragEventArgs e) { base.OnDragOver(e); if (e.Effect == System.Windows.Forms.DragDropEffects.None && IsAcceptableDropItem(e)) // To be defined { e.Effect = System.Windows.Forms.DragDropEffects.Copy; } }
OnDragDrop–이 도형 또는 다이어그램 위에 마우스 포인터가 있을 때 마우스 단추 경우 놓을 경우이 메서드를 호출 OnDragOver(DiagramDragEventArgs e) 이전에 설정 된 e.Effect 이 아닌 다른 값으로 None.
public override void OnDragDrop(DiagramDragEventArgs e) { if (!IsAcceptableDropItem(e)) { base.OnDragDrop(e); } else { // Process the dragged item, for example merging a copy into the diagram ProcessDragDropItem(e); // To be defined } }
OnDoubleClick-이 메서드는 다이어그램을 클릭할 때 호출 됩니다.
자세한 내용은 방법: 모양 또는 데코레이터 클릭 가로채기를 참조하십시오.
정의 IsAcceptableDropItem(e) 여부는 끌어 온된 항목을 사용할 수 ProcessDragDropItem(e) 항목을 삭제 하면 모델을 업데이트 하 고 결정 합니다.이러한 메서드를 이벤트 인수에서 항목 먼저 추출 해야 합니다.이렇게 하는 방법에 대 한 자세한 내용은 는 끌어 온된 항목에 대 한 참조를 가져올 수.
MEF를 사용 하 여 동작 처리기를 정의 합니다.
MEF (관리 되는 확장성 프레임 워크) 최소한의 구성으로 설치할 수 있는 구성 요소를 정의할 수 있습니다.자세한 내용은 MEF(Managed Extensibility Framework)를 참조하십시오.
MEF 제스처 처리기를 정의.
추가 사용자 Dsl 및 DslPackage 프로젝트는 MefExtension 에서 설명 하는 파일 MEF를 사용하여 DSL 확장.
이제는 MEF 구성 요소로 동작 처리기를 정의할 수 있습니다.
// This attribute is defined in the generated file // DslPackage\MefExtension\DesignerExtensionMetaDataAttribute.cs: [MyDslGestureExtension] public class MyGestureHandlerClassName : IGestureExtension { /// <summary> /// Called to determine whether a drag onto the diagram can be accepted. /// </summary> /// <param name="diagramDragEventArgs">Contains a link to the item that is being dragged</param> /// <param name="targetMergeElement">The shape or connector that the mouse is over</param> /// <returns>True if the item can be accepted on the targetMergeElement.</returns> public bool CanDragDrop(ShapeElement targetMergeElement, DiagramDragEventArgs diagramDragEventArgs) { MyShape target = targetMergeElement as MyShape; if (target == null) return false; if (target.IsAcceptableDropItem(diagramDragEventArgs)) return true; return false; } public void OnDragDrop(ShapeElement targetDropElement, DiagramDragEventArgs diagramDragEventArgs) { MyShape target = targetMergeElement as MyShape; if (target == null || ! target.IsAcceptableDropItem(diagramDragEventArgs)) return; // Process the dragged item, for example merging a copy into the diagram: target.ProcessDragDropItem(diagramDragEventArgs); }
여러 종류의 개체를 끌어 온된 경우와 같이 둘 이상의 제스처 처리기 구성 요소를 만들 수 있습니다.
대상 도형, 연결선 또는 다이어그램 클래스에 대 한 partial 클래스 정의 추가 하 고 메서드 정의 IsAcceptableDropItem() 및 ProcessDragDropItem().이러한 메서드의 이벤트 인수에서 끌어 온된 항목을 추출 하 여 시작 해야 합니다.자세한 내용은 는 끌어 온된 항목에 대 한 참조를 가져올 수.
끌어 온된 항목을 디코딩하는 방법
때 사용자가 해당 다이어그램으로 끌 또는 다른 다이어그램의 한 부분에서 드래그 하는 항목에 대 한 정보를 사용할 수 있습니다 [DiagramDragEventArgs].한 화면에 모든 개체 끌기 작업이 시작 수 있기 때문에 데이터 다양 한 형식 중 하나로 사용할 수 있습니다.코드를 처리할 수 있습니다 형식 인식 해야 합니다.
디버깅 모드 항목에 중단점 설정, 끌기 소스 정보는 사용 가능한 형식을 검색 하려면 코드를 실행 OnDragOver() 또는 CanDragDrop().검사 값은 DiagramDragEventArgs 매개 변수.정보는 두 가지 형태로 제공 됩니다.
IDataObject Data–이 속성이 serialize 된 버전의 원본 개체가 일반적으로 둘 이상의 형식으로 전달합니다.가장 유용한 기능입니다.
diagramEventArgs.Data.GetDataFormats() – 끌어온된 개체를 디코딩할 수 있는 형식 목록을 표시 합니다.예를 들어, 사용자가 바탕 화면에서 파일을 끌 경우 파일 이름을 사용할 수 있는 형식을 포함 ("FileNameW").
diagramEventArgs.Data.GetData(format)– 끌어온된 개체를 지정 된 형식으로 디코딩합니다.개체를 적절 한 형식으로 캐스팅 합니다.예를 들면 다음과 같습니다.
string fileName = diagramEventArgs.Data.GetData("FileNameW") as string;
또한 사용자 고유의 사용자 지정 형식으로 원본에서 모델 버스 참조와 같은 개체를 전송할 수 있습니다.자세한 내용은 를 보낼 모델 버스 참조에서 드래그 앤 드롭 하는 방법.
ElementGroupPrototypePrototype– DSL 또는 UML 모델에서 항목을 끌어 사용자가이 속성을 사용 합니다.요소 그룹 프로토타입에 하나 이상의 개체, 링크 및 해당 속성 값을 포함합니다.붙여 넣기 작업 및 도구 상자에서 요소를 추가 하는 경우에 사용 됩니다.프로토타입 객체 및 유형을 Guid로 식별 됩니다.예를 들어,이 코드 클래스 요소 UML 다이어그램 또는 UML 모델 탐색기에서 드래그 수 있습니다.
private bool IsAcceptableDropItem(DiagramDragEventArgs e) { return e.Prototype != null && e.Prototype.RootProtoElements.Any(element => element.DomainClassId.ToString() == "3866d10c-cc4e-438b-b46f-bb24380e1678"); // Accept UML class shapes. // Or, from another DSL: SourceNamespace.SourceShapeClass.DomainClassId }
UML 셰이프를 받아들이도록 실험에 의해 UML 셰이프 클래스 Guid를 확인 합니다.다이어그램에서 요소를 두 개 이상의 형식이 일반적으로 임을 기억 하십시오.또한 DSL 또는 UML 다이어그램에서 끌어 온 개체 모델 요소 셰이프를 구분 합니다.
DiagramDragEventArgs또한 현재 마우스 포인터 위치 및 사용자가 ctrl 키, alt 키 또는 SHIFT 키 눌러 됩니다 여부를 나타내는 속성이 있습니다.
원래 드래그 요소를 얻는 방법
Data 및 Prototype 속성에는 이벤트 인수 끌어 놓은 모양에 대 한 참조만 포함 되어 있습니다.프로토타입 방식으로 파생 된 DSL 대상 개체를 만들 경우 일반적으로 원본에 액세스할 수 예를 들어, 파일 내용 읽기, 도형으로 표시 하는 모델 요소를 탐색 하면.이를 위해 Visual Studio 모델 버스를 사용할 수 있습니다.
DSL 프로젝트 모델 버스를 준비 하려면
DSL 원본으로 액세스할 수 있도록 Visual Studio 모델 버스.
다운로드 하 고 설치 하지 않은 경우 Visual Studio 모델 버스 확장을 설치 합니다.자세한 내용은 시각화 및 모델링 SDK.
DSL 정의 파일 원본의 DSL에서 DSL 디자이너를 엽니다.디자인 화면을 마우스 오른쪽 단추로 클릭 하 고 다음을 클릭 사용 Modelbus.대화 상자에 있는 옵션 중 하나 또는 모두를 선택 합니다.확인을 클릭합니다.새 프로젝트 "ModelBus" DSL 솔루션에 추가 됩니다.
클릭 모든 템플릿 변환 하 고 솔루션을 다시 빌드합니다.
원본의 DSL 개체 보내기
ElementOperations 하위 클래스에서 재정의 Copy() 하 여 Idataobject에 모델 버스 참조 (MBR)를 인코딩합니다.이 메서드는 사용자 소스 다이어그램에서 끌기 시작할 때 호출 됩니다.사용자는 대상 다이어그램에서 떨어지면 인코딩된 MBR에 다음 Idataobject에 사용할 수 있습니다.
using Microsoft.VisualStudio.Modeling; using Microsoft.VisualStudio.Modeling.Shell; using Microsoft.VisualStudio.Modeling.Diagrams; using Microsoft.VisualStudio.Modeling.Integration; using Microsoft.VisualStudio.Modeling.Integration.Shell; using System.Drawing; // PointF using System.Collections.Generic; // ICollection using System.Windows.Forms; // for IDataObject ... public class MyElementOperations : DesignSurfaceElementOperations { public override void Copy(System.Windows.Forms.IDataObject data, System.Collections.Generic.ICollection<ModelElement> elements, ClosureType closureType, System.Drawing.PointF sourcePosition) { base.Copy(data, elements, closureType, sourcePosition); // Get the ModelBus service: IModelBus modelBus = this.Store.GetService(typeof(SModelBus)) as IModelBus; DocData docData = ((VSDiagramView)this.Diagram.ActiveDiagramView).DocData; string modelFile = docData.FileName; // Get an adapterManager for the target DSL: ModelBusAdapterManager manager = (modelBus.FindAdapterManagers(modelFile).First()); ModelBusReference modelReference = manager.CreateReference(modelFile); ModelBusReference elementReference = null; using (ModelBusAdapter adapter = modelBus.CreateAdapter(modelReference)) { elementReference = adapter.GetElementReference(elements.First()); } data.SetData("ModelBusReference", elementReference); } ...}
모델 버스 참조 대상 DSL 또는 UML 프로젝트에서는 DSL에서 받을 수
대상 DSL 프로젝트에 프로젝트 참조를 추가 합니다.
Dsl 프로젝트입니다.
ModelBus 프로젝트입니다.
동작 처리기 코드 파일에는 다음과 같은 네임 스페이스 참조를 추가 합니다.
using Microsoft.VisualStudio.Modeling; using Microsoft.VisualStudio.Modeling.ExtensionEnablement; using Microsoft.VisualStudio.Modeling.Diagrams; using Microsoft.VisualStudio.Modeling.Diagrams.ExtensionEnablement; using Microsoft.VisualStudio.Modeling.Integration; using SourceDslNamespace; using SourceDslNamespace.ModelBusAdapters;
다음 샘플 소스 모델 요소에 액세스 하는 방법을 보여 줍니다.
partial class MyTargetShape // or diagram or connector { internal void ProcessDragDropItem(DiagramDragEventArgs diagramDragEventArgs) { // Verify that we're being passed an Object Shape. ElementGroupPrototype prototype = diagramDragEventArgs.Prototype; if (prototype == null) return; if (Company.InstanceDiagrams.ObjectShape.DomainClassId != prototype.RootProtoElements.First().DomainClassId) return; // - This is an ObjectShape. // - We need to access the originating Store, find the shape, and get its object. IModelBus modelBus = targetDropElement.Store.GetService(typeof(SModelBus)) as IModelBus; // Unpack the MBR that was packed in Copy: ModelBusReference reference = diagramDragEventArgs.Data.GetData("ModelBusReference") as ModelBusReference; using (SourceDslAdapter adapter = modelBus.CreateAdapter(reference) as SourceDslAdapter) { using (ILinkedUndoTransaction t = LinkedUndoContext.BeginTransaction("doing things")) { // Quickest way to get the shape from the MBR: ObjectShape firstShape = adapter.ResolveElementReference<ObjectShape>(reference); // But actually there might be several shapes - so get them from the prototype instead: IElementDirectory remoteDirectory = adapter.Store.ElementDirectory; foreach (Guid shapeGuid in prototype.SourceRootElementIds) { PresentationElement pe = remoteDirectory.FindElement(shapeGuid) as PresentationElement; if (pe == null) continue; SourceElement instance = pe.ModelElement as SourceElement; if (instance == null) continue; // Do something with the object: instance... } t.Commit(); } } }
UML 모델을 기반으로 요소를 적용 합니다.
다음 코드 예제에서는 개체를 받아들이는 UML 다이어그램에서 삭제 합니다.
using Microsoft.VisualStudio.ArchitectureTools.Extensibility; using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml; using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation; using Microsoft.VisualStudio.Modeling; using Microsoft.VisualStudio.Modeling.Diagrams; using Microsoft.VisualStudio.Modeling.Diagrams.ExtensionEnablement; using Microsoft.VisualStudio.Uml.Classes; using System; using System.ComponentModel.Composition; using System.Linq; ... partial class TargetShape { internal void ProcessDragDropItem(DiagramDragEventArgs diagramDragEventArgs) { EnvDTE.DTE dte = this.Store.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE; // Find the UML project foreach (EnvDTE.Project project in dte.Solution.Projects) { IModelingProject modelingProject = project as IModelingProject; if (modelingProject == null) continue; // not a modeling project IModelStore store = modelingProject.Store; if (store == null) return; foreach (IDiagram dd in store.Diagrams()) { // Get Modeling.Diagram that implements UML.IDiagram: Diagram diagram = dd.GetObject<Diagram>(); foreach (Guid elementId in e.Prototype.SourceRootElementIds) { ShapeElement shape = diagram.Partition.ElementDirectory.FindElement(elementId) as ShapeElement; if (shape == null) continue; // This example assumes the shape is a UML class: IClass classElement = shape.ModelElement as IClass; if (classElement == null) continue; // Now do something with the UML class element ... } } break; // don't try any more projects } } }
구획 항목 끌기 마우스를 사용 하 여:
셰이프 필드에서 마우스 동작을 차단 하는 처리기를 작성할 수 있습니다.다음 예제에서는 항목에는 마우스를 드래그 하 여 순서를 변경할 수가 있습니다.
사용 하 여이 예제를 빌드하려면 솔루션 만들기는 클래스 다이어그램 솔루션 템플릿.코드 파일을 추가 하 고 다음 코드를 추가 합니다.네임 스페이스는 사용자 고유의 것으로 조정 합니다.
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Design;
using Microsoft.VisualStudio.Modeling.Diagrams;
using System.Collections.Generic;
using System.Linq;
// This sample allows users to re-order items in a compartment shape by dragging.
// This example is built on the "Class Diagrams" solution template of VMSDK (DSL Tools).
// You will need to change the following domain class names to your own:
// ClassShape = a compartment shape
// ClassModelElement = the domain class displayed using a ClassShape
// This code assumes that the embedding relationships displayed in the compartments
// don't use inheritance (don't have base or derived domain relationships).
namespace Company.CompartmentDrag // EDIT.
{
/// <summary>
/// Manage the mouse while dragging a compartment item.
/// </summary>
public class CompartmentDragMouseAction : MouseAction
{
private ModelElement sourceChild;
private ClassShape sourceShape;
private RectangleD sourceCompartmentBounds;
public CompartmentDragMouseAction(ModelElement sourceChildElement, ClassShape sourceParentShape, RectangleD bounds)
: base (sourceParentShape.Diagram)
{
sourceChild = sourceChildElement;
sourceShape = sourceParentShape;
sourceCompartmentBounds = bounds; // For cursor.
}
/// <summary>
/// Call back to the source shape to drop the dragged item.
/// </summary>
/// <param name="e"></param>
protected override void OnMouseUp(DiagramMouseEventArgs e)
{
base.OnMouseUp(e);
sourceShape.DoMouseUp(sourceChild, e);
this.Cancel(e.DiagramClientView);
e.Handled = true;
}
/// <summary>
/// Ideally, this shouldn't happen. This action should only be active
/// while the mouse is still pressed. However, it can happen if you
/// move the mouse rapidly out of the source shape, let go, and then
/// click somewhere else in the source shape. Yuk.
/// </summary>
/// <param name="e"></param>
protected override void OnMouseDown(DiagramMouseEventArgs e)
{
base.OnMouseDown(e);
this.Cancel(e.DiagramClientView);
e.Handled = false;
}
/// <summary>
/// Display an appropriate cursor while the drag is in progress:
/// Up-down arrow if we are inside the original compartment.
/// No entry if we are elsewhere.
/// </summary>
/// <param name="currentCursor"></param>
/// <param name="diagramClientView"></param>
/// <param name="mousePosition"></param>
/// <returns></returns>
public override System.Windows.Forms.Cursor GetCursor(System.Windows.Forms.Cursor currentCursor, DiagramClientView diagramClientView, PointD mousePosition)
{
// If the cursor is inside the original compartment, show up-down cursor.
return sourceCompartmentBounds.Contains(mousePosition)
? System.Windows.Forms.Cursors.SizeNS // Up-down arrow.
: System.Windows.Forms.Cursors.No;
}
}
/// <summary>
/// Override some methods of the compartment shape.
/// *** GenerateDoubleDerived must be set for this shape in DslDefinition.dsl. ****
/// </summary>
public partial class ClassShape
{
/// <summary>
/// Model element that is being dragged.
/// </summary>
private static ClassModelElement dragStartElement = null;
/// <summary>
/// Absolute bounds of the compartment, used to set the cursor.
/// </summary>
private static RectangleD compartmentBounds;
/// <summary>
/// Attach mouse listeners to the compartments for the shape.
/// This is called once per compartment shape.
/// The base method creates the compartments for this shape.
/// </summary>
public override void EnsureCompartments()
{
base.EnsureCompartments();
foreach (Compartment compartment in this.NestedChildShapes.OfType<Compartment>())
{
compartment.MouseDown += new DiagramMouseEventHandler(compartment_MouseDown);
compartment.MouseUp += new DiagramMouseEventHandler(compartment_MouseUp);
compartment.MouseMove += new DiagramMouseEventHandler(compartment_MouseMove);
}
}
/// <summary>
/// Remember which item the mouse was dragged from.
/// We don't create an Action immediately, as this would inhibit the
/// inline text editing feature. Instead, we just remember the details
/// and will create an Action when/if the mouse moves off this list item.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void compartment_MouseDown(object sender, DiagramMouseEventArgs e)
{
dragStartElement = e.HitDiagramItem.RepresentedElements.OfType<ClassModelElement>().FirstOrDefault();
compartmentBounds = e.HitDiagramItem.Shape.AbsoluteBoundingBox;
}
/// <summary>
/// When the mouse moves away from the initial list item, but still inside the compartment,
/// create an Action to supervise the cursor and handle subsequent mouse events.
/// Transfer the details of the initial mouse position to the Action.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void compartment_MouseMove(object sender, DiagramMouseEventArgs e)
{
if (dragStartElement != null)
{
if (dragStartElement != e.HitDiagramItem.RepresentedElements.OfType<ClassModelElement>().FirstOrDefault())
{
e.DiagramClientView.ActiveMouseAction = new CompartmentDragMouseAction(dragStartElement, this, compartmentBounds);
dragStartElement = null;
}
}
}
/// <summary>
/// User has released the mouse button.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void compartment_MouseUp(object sender, DiagramMouseEventArgs e)
{
dragStartElement = null;
}
/// <summary>
/// Forget the source item if mouse up occurs outside the
/// compartment.
/// </summary>
/// <param name="e"></param>
public override void OnMouseUp(DiagramMouseEventArgs e)
{
base.OnMouseUp(e);
dragStartElement = null;
}
/// <summary>
/// Called by the Action when the user releases the mouse.
/// If we are still on the same compartment but in a different list item,
/// move the starting item to the position of the current one.
/// </summary>
/// <param name="dragFrom"></param>
/// <param name="e"></param>
public void DoMouseUp(ModelElement dragFrom, DiagramMouseEventArgs e)
{
// Original or "from" item:
ClassModelElement dragFromElement = dragFrom as ClassModelElement;
// Current or "to" item:
ClassModelElement dragToElement = e.HitDiagramItem.RepresentedElements.OfType<ClassModelElement>().FirstOrDefault();
if (dragFromElement != null && dragToElement != null)
{
// Find the common parent model element, and the relationship links:
ElementLink parentToLink = GetEmbeddingLink(dragToElement);
ElementLink parentFromLink = GetEmbeddingLink(dragFromElement);
if (parentToLink != parentFromLink && parentFromLink != null && parentToLink != null)
{
// Get the static relationship and role (= end of relationship):
DomainRelationshipInfo relationshipFrom = parentFromLink.GetDomainRelationship();
DomainRoleInfo parentFromRole = relationshipFrom.DomainRoles[0];
// Get the node in which the element is embedded, usually the element displayed in the shape:
ModelElement parentFrom = parentFromLink.LinkedElements[0];
// Same again for the target:
DomainRelationshipInfo relationshipTo = parentToLink.GetDomainRelationship();
DomainRoleInfo parentToRole = relationshipTo.DomainRoles[0];
ModelElement parentTo = parentToLink.LinkedElements[0];
// Mouse went down and up in same parent and same compartment:
if (parentTo == parentFrom && relationshipTo == relationshipFrom)
{
// Find index of target position:
int newIndex = 0;
var elementLinks = parentToRole.GetElementLinks(parentTo);
foreach (ElementLink link in elementLinks)
{
if (link == parentToLink) { break; }
newIndex++;
}
if (newIndex < elementLinks.Count)
{
using (Transaction t = parentFrom.Store.TransactionManager.BeginTransaction("Move list item"))
{
parentFromLink.MoveToIndex(parentFromRole, newIndex);
t.Commit();
}
}
}
}
}
}
/// <summary>
/// Get the embedding link to this element.
/// Assumes there is no inheritance between embedding relationships.
/// (If there is, you need to make sure you've got the relationship
/// that is represented in the shape compartment.)
/// </summary>
/// <param name="child"></param>
/// <returns></returns>
ElementLink GetEmbeddingLink(ClassModelElement child)
{
foreach (DomainRoleInfo role in child.GetDomainClass().AllEmbeddedByDomainRoles)
{
foreach (ElementLink link in role.OppositeDomainRole.GetElementLinks(child))
{
// Just the assume the first embedding link is the only one.
// Not a valid assumption if one relationship is derived from another.
return link;
}
}
return null;
}
}
}