Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dalam bahasa khusus domain (DSL) yang dibuat dengan Visualisasi Visualisasi dan Pemodelan SDK Visual Studio, Anda dapat mengubah apa yang terjadi saat pengguna menyalin dan menempelkan elemen.
Perilaku Salin dan Tempel Standar
Untuk mengaktifkan penyalinan , atur properti Aktifkan Salin Tempel dari simpul Editor di DSL Explorer.
Secara default, ketika pengguna menyalin elemen ke clipboard, elemen berikut juga disalin:
Turunan yang disematkan dari elemen yang dipilih. (Artinya, elemen yang merupakan target hubungan penyematan yang bersumber pada elemen yang disalin.)
Tautan hubungan antara elemen yang disalin.
Aturan ini berlaku secara rekursif ke elemen dan tautan yang disalin.

Elemen dan tautan yang disalin diserialisasikan dan disimpan dalam ElementGroupPrototype (EGP), yang ditempatkan di clipboard.
Gambar elemen yang disalin juga ditempatkan di clipboard. Ini memungkinkan pengguna untuk menempelkan ke aplikasi lain seperti Word.
Pengguna dapat menempelkan elemen yang disalin ke target yang dapat menerima elemen sesuai dengan Definisi DSL. Misalnya, dalam DSL yang dihasilkan dari templat solusi komponen, pengguna dapat menempelkan port ke komponen, tetapi tidak ke diagram; dan dapat menempelkan komponen ke diagram, tetapi tidak ke komponen lain.
Menyesuaikan Perilaku Salin dan Tempel
Untuk informasi selengkapnya tentang menyesuaikan model dengan menggunakan kode program, lihat Menavigasi dan Memperbarui Model dalam Kode Program.
Aktifkan atau nonaktifkan salin, potong, dan tempel. Di DSL Explorer, atur properti Aktifkan Salin Tempel dari simpul Editor .
Salin tautan ke target yang sama. Misalnya, untuk memiliki kotak komentar yang disalin yang ditautkan ke elemen subjek yang sama. Atur properti Sebarkan Salin peran ke Sebarkan salinan ke tautan saja. Untuk informasi selengkapnya, lihat Menyesuaikan Perilaku Salin Tautan.
Salin elemen tertaut. Misalnya, saat Anda menyalin elemen baru, salinan kotak komentar tertaut juga dibuat. Atur properti Sebarkan Salin peran ke Sebarkan salinan ke tautan dan pemutar peran yang berlawanan. Untuk informasi selengkapnya, lihat Menyesuaikan Perilaku Salin Tautan.
Menduplikasi elemen dengan cepat dengan menyalin dan menempelkan. Biasanya, item yang baru saja Anda salin masih dipilih, dan Anda tidak dapat menempelkan jenis elemen yang sama ke dalamnya. Tambahkan Direktif Gabungan Elemen ke kelas domain, dan atur untuk meneruskan penggabungan ke kelas induk. Ini akan memiliki efek yang sama pada operasi seret. Untuk informasi selengkapnya, lihat Menyesuaikan Pembuatan dan Gerakan Elemen.
- atau -
Pilih diagram sebelum menempelkan elemen, dengan menimpa ClipboardCommandSet.ProcessOnPasteCommand(). Tambahkan kode ini dalam file kustom di proyek DslPackage:
namespace Company.MyDsl {
using System.Linq;
using Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling.Shell;
partial class MyDslClipboardCommandSet
{
protected override void ProcessOnMenuPasteCommand()
{
// Deselect the current selection after copying:
Diagram diagram = (this.CurrentModelingDocView as SingleDiagramDocView).Diagram;
this.CurrentModelingDocView
.SelectObjects(1, new object[] { diagram }, 0);
}
} }
Buat tautan tambahan saat pengguna menempelkan ke target yang dipilih. Misalnya, saat kotak komentar ditempelkan ke elemen, tautan dibuat di antaranya. Tambahkan Arahan Gabungan Elemen ke kelas domain target, dan atur untuk memproses penggabungan dengan menambahkan tautan. Ini akan memiliki efek yang sama pada operasi seret. Untuk informasi selengkapnya, lihat Menyesuaikan Pembuatan dan Gerakan Elemen.
- atau -
Ambil alih ClipboardCommandSet.ProcessOnPasteCommand() untuk membuat tautan tambahan setelah memanggil metode dasar.
Sesuaikan format di mana elemen dapat disalin ke aplikasi eksternal - misalnya, untuk menambahkan batas ke formulir bitmap.
Ambil alih MyDslClipboardCommandSet.ProcessOnMenuCopyCommand() dalam proyek DslPackage.
Kustomisasi bagaimana elemen disalin ke clipboard dengan perintah salin, tetapi tidak dalam operasi seret.
Ambil alih MyDslClipboardCommandSet.CopyModelElementsIntoElementGroupPrototype() dalam proyek DslPackage.
Pertahankan tata letak bentuk melalui salin dan tempel. Saat pengguna menyalin beberapa bentuk, Anda dapat mempertahankan posisi relatif mereka saat ditempelkan. Teknik ini ditunjukkan oleh contoh di sampel VMSDK: Diagram Sirkuit.
Untuk mencapai efek ini, tambahkan bentuk dan konektor ke ElementGroupPrototype yang disalin. Metode yang paling nyaman untuk diambil alih adalah ElementOperations.CreateElementGroupPrototype(). Untuk melakukan ini, tambahkan kode berikut ke proyek Dsl:
public class MyElementOperations : DesignSurfaceElementOperations
{
// Create an EGP to add to the clipboard.
// Called when the elements to be copied have been
// collected into an ElementGroup.
protected override ElementGroupPrototype CreateElementGroupPrototype(ElementGroup elementGroup, ICollection<ModelElement> elements, ClosureType closureType)
{
// Add the shapes and connectors:
// Get the elements already in the group:
ModelElement[] mels = elementGroup.ModelElements
.Concat(elementGroup.ElementLinks) // Omit if the paste target is not the diagram.
.ToArray();
// Get their shapes:
IEnumerable<PresentationElement> shapes =
mels.SelectMany(mel =>
PresentationViewsSubject.GetPresentation(mel));
elementGroup.AddRange(shapes);
return base.CreateElementGroupPrototype
(elementGroup, elements, closureType);
}
public MyElementOperations(IServiceProvider serviceProvider, ElementOps1Diagram diagram)
: base(serviceProvider, diagram)
{ }
}
// Replace the standard ElementOperations
// singleton with your own:
partial class MyDslDiagram // EDIT NAME
{
/// <summary>
/// Singleton ElementOperations attached to this diagram.
/// </summary>
public override DesignSurfaceElementOperations ElementOperations
{
get
{
if (singleton == null)
{
singleton = new MyElementOperations(this.Store as IServiceProvider, this);
}
return singleton;
}
}
private MyElementOperations singleton = null;
}
Tempel bentuk di lokasi yang dipilih, seperti posisi kursor saat ini. Saat pengguna menyalin beberapa bentuk, Anda dapat mempertahankan posisi relatif mereka saat ditempelkan. Teknik ini ditunjukkan oleh contoh di sampel VMSDK: Diagram Sirkuit.
Untuk mencapai efek ini, ambil alih ClipboardCommandSet.ProcessOnMenuPasteCommand() untuk menggunakan versi spesifik lokasi dari ElementOperations.Merge(). Untuk melakukan ini, tambahkan kode berikut dalam proyek DslPackage:
partial class MyDslClipboardCommandSet // EDIT NAME
{
/// <summary>
/// This method assumes we only want to paste things onto the diagram
/// - not onto anything contained in the diagram.
/// The base method pastes in a free space on the diagram.
/// But if the menu was used to invoke paste, we want to paste in the cursor position.
/// </summary>
protected override void ProcessOnMenuPasteCommand()
{
NestedShapesSampleDocView docView = this.CurrentModelingDocView as NestedShapesSampleDocView;
// Retrieve data from clipboard:
System.Windows.Forms.IDataObject data = System.Windows.Forms.Clipboard.GetDataObject();
Diagram diagram = docView.CurrentDiagram;
if (diagram == null) return;
if (!docView.IsContextMenuShowing)
{
// User hit CTRL+V - just use base method.
// Deselect anything that's selected, otherwise
// pasted item will be incompatible:
if (!this.IsDiagramSelected())
{
docView.SelectObjects(1, new object[] { diagram }, 0);
}
// Paste into a convenient spare space on diagram:
base.ProcessOnMenuPasteCommand();
}
else
{
// User right-clicked - paste at mouse position.
// Utility class:
DesignSurfaceElementOperations op = diagram.ElementOperations;
ShapeElement pasteTarget = diagram;
// Check whether what's in the paste buffer is acceptable on the target.
if (pasteTarget != null && op.CanMerge(pasteTarget, data))
{
// Although op.Merge would be a no-op if CanMerge failed, we check CanMerge first
// so that we don't create an empty transaction (after which Undo would be no-op).
using (Transaction t = diagram.Store.TransactionManager.BeginTransaction("paste"))
{
PointD place = docView.ContextMenuMousePosition;
op.Merge(pasteTarget, data, PointD.ToPointF(place));
t.Commit();
}
}
}
}
}
Biarkan pengguna menyeret dan menghilangkan elemen. Lihat Cara: Menambahkan Handler Seret dan Letakkan.
Menyesuaikan Perilaku Salin Tautan
Ketika pengguna menyalin elemen, perilaku standar adalah bahwa elemen yang disematkan juga disalin. Anda dapat mengubah perilaku penyalinan standar. Di Definisi DSL, pilih peran di satu sisi hubungan dan di jendela Properti atur nilai Sebarkan Salin .

Ada tiga nilai:
Jangan menyebarluaskan salinan
Sebarkan salinan ke tautan saja - ketika grup ditempelkan, salinan baru tautan ini akan merujuk ke elemen yang ada di ujung lain tautan.
Sebarkan salinan ke tautan dan pemutar peran yang berlawanan - grup yang disalin menyertakan salinan elemen di ujung tautan lainnya.

Perubahan yang Anda buat akan memengaruhi elemen dan gambar yang disalin.
Perilaku Salin dan Tempel Pemrograman
Banyak aspek perilaku DSL sehubungan dengan penyalinan, tempel, pembuatan, dan penghapusan objek diatur oleh instans ElementOperations yang digabungkan dengan diagram. Anda dapat memodifikasi perilaku DSL Anda dengan mengambil kelas Anda sendiri dari ElementOperations dan mengambil alih ElementOperations properti kelas diagram Anda.
Tip
Untuk informasi selengkapnya tentang menyesuaikan model dengan menggunakan kode program, lihat Menavigasi dan Memperbarui Model dalam Kode Program.


Untuk menentukan ElementOperations Anda sendiri
Dalam file baru di proyek DSL Anda, buat kelas yang berasal dari DesignSurfaceElementOperations.
Tambahkan definisi kelas parsial untuk kelas diagram Anda. Nama kelas ini dapat ditemukan di Dsl\GeneratedCode\Diagrams.cs.
Di kelas diagram, ambil alih ElementOperations untuk mengembalikan instans subkelas ElementOperations Anda. Anda harus mengembalikan instans yang sama di setiap panggilan.
Tambahkan kode ini dalam file kode kustom di proyek DslPackage:
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling.Diagrams.ExtensionEnablement;
public partial class MyDslDiagram
{
public override DesignSurfaceElementOperations ElementOperations
{
get
{
if (this.elementOperations == null)
{
this.elementOperations = new MyElementOperations(this.Store as IServiceProvider, this);
}
return this.elementOperations;
}
}
private MyElementOperations elementOperations = null;
}
public class MyElementOperations : DesignSurfaceElementOperations
{
public MyElementOperations(IServiceProvider serviceProvider, MyDslDiagram diagram)
: base(serviceProvider, diagram)
{ }
// Overridden methods follow
}
Menerima item yang diseret dari model lain
ElementOperations juga dapat digunakan untuk menentukan perilaku penyalinan, pemindahan, penghapusan, dan seret dan letakkan. Sebagai demonstrasi penggunaan ElementOperations, contoh yang diberikan di sini mendefinisikan perilaku seret dan letakkan kustom. Namun, untuk tujuan tersebut Anda mungkin mempertimbangkan pendekatan alternatif yang dijelaskan dalam Cara: Menambahkan Handler Seret dan Letakkan, yang lebih dapat diperluas.
Tentukan dua metode di kelas ElementOperations Anda:
CanMerge(ModelElement targetElement, System.Windows.Forms.IDataObject data)yang menentukan apakah elemen sumber dapat diseret ke bentuk target, konektor, atau diagram.MergeElementGroupPrototype(ModelElement targetElement, ElementGroupPrototype sourcePrototype)yang menggabungkan elemen sumber ke dalam target.
CanMerge()
CanMerge() dipanggil untuk menentukan umpan balik yang harus diberikan kepada pengguna saat mouse bergerak melintasi diagram. Parameter ke metode adalah elemen di mana mouse melayang, dan data tentang sumber tempat operasi seret telah dilakukan. Pengguna dapat menyeret dari mana saja di layar. Oleh karena itu, objek sumber dapat dari berbagai jenis dan dapat diserialisasikan dalam format yang berbeda. Jika sumbernya adalah model DSL atau UML, parameter data adalah serialisasi dari ElementGroupPrototype. Operasi seret, salin, dan kotak alat menggunakan ElementGroupPrototypes untuk mewakili fragmen model.
Prototipe Grup Elemen dapat berisi sejumlah elemen dan tautan. Jenis elemen dapat diidentifikasi oleh GUID mereka. GUID adalah bentuk yang diseret, bukan elemen model yang mendasar. Dalam contoh berikut, CanMerge() mengembalikan true jika bentuk kelas dari diagram UML diseret ke diagram ini.
public override bool CanMerge(ModelElement targetShape, System.Windows.Forms.IDataObject data)
{
// Extract the element prototype from the data.
ElementGroupPrototype prototype = ElementOperations.GetElementGroupPrototype(this.ServiceProvider, data);
if (targetShape is MyTargetShape && prototype != null &&
prototype.RootProtoElements.Any(rootElement =>
rootElement.DomainClassId.ToString()
== "3866d10c-cc4e-438b-b46f-bb24380e1678")) // Guid of UML Class shapes
// or SourceClass.DomainClassId
return true;
return base.CanMerge(targetShape, data);
}
MergeElementGroupPrototype()
Metode ini dipanggil ketika pengguna menjatuhkan elemen ke diagram, bentuk, atau konektor. Ini harus menggabungkan konten yang diseret ke dalam elemen target. Dalam contoh ini, kode menentukan apakah kode mengenali kombinasi jenis target dan prototipe; jika demikian, metode mengonversi elemen yang diseret menjadi prototipe elemen yang harus ditambahkan ke model. Metode dasar dipanggil untuk melakukan penggabungan, salah satu elemen yang dikonversi atau tidak dikonversi.
public override void MergeElementGroupPrototype(ModelElement targetShape, ElementGroupPrototype sourcePrototype)
{
ElementGroupPrototype prototypeToMerge = sourcePrototype;
MyTargetShape pel = targetShape as MyTargetShape;
if (pel != null)
{
prototypeToMerge = ConvertDraggedTypeToLocal(pel, sourcePrototype);
}
if (prototypeToMerge != null)
base.MergeElementGroupPrototype(targetShape, prototypeToMerge);
}
Contoh ini berkaitan dengan elemen kelas UML yang diseret dari diagram kelas UML. DSL tidak dirancang untuk menyimpan kelas UML secara langsung, tetapi sebaliknya, kami membuat elemen DSL untuk setiap kelas UML yang diseret. Ini akan berguna, misalnya, jika DSL adalah diagram instans. Pengguna dapat menyeret kelas ke diagram untuk membuat instans kelas tersebut.
private ElementGroupPrototype ConvertDraggedTypeToLocal (MyTargetShape snapshot, ElementGroupPrototype prototype)
{
// Find the UML project:
EnvDTE.DTE dte = snapshot.Store.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
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) continue;
// Look for the shape that was dragged:
foreach (IDiagram umlDiagram in store.Diagrams())
{
// Get modeling diagram that implements UML diagram:
Diagram diagram = umlDiagram.GetObject<Diagram>();
Guid elementId = prototype.SourceRootElementIds.FirstOrDefault();
ShapeElement shape = diagram.Partition.ElementDirectory.FindElement(elementId) as ShapeElement;
if (shape == null) continue;
IClass classElement = shape.ModelElement as IClass;
if (classElement == null) continue;
// Create a prototype of elements in my DSL, based on the UML element:
Instance instance = new Instance(snapshot.Store);
instance.Type = classElement.Name;
// Pack them into a prototype:
ElementGroup group = new ElementGroup(instance);
return group.CreatePrototype();
}
}
return null;
}
Perilaku Salin Standar
Kode di bagian ini menunjukkan metode yang dapat Anda ambil alih untuk mengubah perilaku penyalinan. Untuk membantu Anda melihat cara mencapai kustomisasi Anda sendiri, bagian ini menunjukkan kode yang mengambil alih metode yang terlibat dalam penyalinan, tetapi tidak mengubah perilaku standar.
Saat pengguna menekan CTRL+C atau menggunakan perintah menu Salin, metode ProcessOnMenuCopyCommand dipanggil. Anda dapat melihat bagaimana ini disiapkan di DslPackage\Generated Code\CommandSet.cs. Untuk informasi selengkapnya tentang cara perintah disiapkan, lihat Cara: Menambahkan Perintah ke Menu Pintasan.
Anda dapat mengambil alih ProcessOnMenuCopyCommand dengan menambahkan definisi kelas parsial MyDslClipboardCommandSet dalam proyek DslPackage.
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
partial class MyDslClipboardCommandSet
{
/// <summary>
/// Override ProcessOnMenuCopyCommand() to copy elements to the
/// clipboard in different formats, or to perform additional tasks
/// before or after copying - for example deselect the copied elements.
/// </summary>
protected override void ProcessOnMenuCopyCommand()
{
IList<ModelElement> selectedModelElements = this.SelectedElements;
if (selectedModelElements.Count == 0) return;
// System container for clipboard data.
// The IDataObject can contain data in several formats.
IDataObject dataObject = new DataObject();
Bitmap bitmap = null; // For export to other programs.
try
{
#region Create EGP for copying to a DSL.
this.CopyModelElementsIntoElementGroupPrototype
(dataObject, selectedModelElements);
#endregion
#region Create bitmap for copying to another application.
// Find all the shapes associated with this selection:
List<ShapeElement> shapes = new List<ShapeElement>(
this.ResolveExportedShapesForClipboardImages
(dataObject, selectedModelElements));
bitmap = this.CreateBitmapForClipboard(shapes);
if (bitmap != null)
{
dataObject.SetData(DataFormats.Bitmap, bitmap);
}
#endregion
// Add the data to the clipboard:
Clipboard.SetDataObject(dataObject, true, 5, 100);
}
finally
{
// Dispose bitmap after SetDataObject:
if (bitmap != null) bitmap.Dispose();
}
}
/// <summary>
/// Override this to customize the element group that is copied to the clipboard.
/// </summary>
protected override void CopyModelElementsIntoElementGroupPrototype(IDataObject dataObject, IList<ModelElement> selectedModelElements)
{
return this.ElementOperations.Copy(dataObject, selectedModelElements);
}
}
Setiap diagram memiliki instans singleton ElementOperations. Anda dapat menyediakan turunan Anda sendiri. File ini, yang dapat ditempatkan dalam proyek DSL, akan berulah sama dengan kode yang ditimpanya:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
namespace Company.MyDsl
{
partial class MyDslDiagram
{
/// <summary>
/// Singleton ElementOperations attached to this diagram.
/// </summary>
public override DesignSurfaceElementOperations ElementOperations
{
get
{
if (this.elementOperations == null)
{
this.elementOperations = new MyElementOperations(this.Store as IServiceProvider, this);
}
return this.elementOperations;
}
}
private MyElementOperations elementOperations = null;
}
// Our own version of ElementOperations so that we can override:
public class MyElementOperations : DesignSurfaceElementOperations
{
public MyElementOperations(IServiceProvider serviceProvider, ElementOps1Diagram diagram)
: base(serviceProvider, diagram)
{ }
/// <summary>
/// Copy elements to the clipboard data.
/// Provides a hook for adding custom data.
/// </summary>
public override void Copy(System.Windows.Forms.IDataObject data,
ICollection<ModelElement> elements,
ClosureType closureType,
System.Drawing.PointF sourcePosition)
{
if (CanAddElementGroupFormat(elements, closureType))
{
AddElementGroupFormat(data, elements, closureType);
}
// Override these to store additional data:
if (CanAddCustomFormat(elements, closureType))
{
AddCustomFormat(data, elements, closureType, sourcePosition);
}
}
protected override void AddElementGroupFormat(System.Windows.Forms.IDataObject data, ICollection<ModelElement> elements, ClosureType closureType)
{
// Add the selected elements and those implied by the propagate copy rules:
ElementGroup elementGroup = this.CreateElementGroup(elements, closureType);
// Mark all the elements that are not embedded under other elements:
this.MarkRootElements(elementGroup, elements, closureType);
// Store in the clipboard data:
ElementGroupPrototype elementGroupPrototype = this.CreateElementGroupPrototype(elementGroup, elements, closureType);
data.SetData(ElementGroupPrototype.DefaultDataFormatName, elementGroupPrototype);
}
/// <summary>
/// Override this to store additional elements in the element group:
/// </summary>
protected override ElementGroupPrototype CreateElementGroupPrototype(ElementGroup elementGroup, ICollection<ModelElement> elements, ClosureType closureType)
{
ElementGroupPrototype prototype = new ElementGroupPrototype(this.Partition, elementGroup.RootElements, elementGroup);
return prototype;
}
/// <summary>
/// Create an element group from the given starting elements, using the
/// copy propagation rules specified in the DSL Definition.
/// By default, this includes all the embedded descendants of the starting elements,
/// and also includes reference links where both ends are already included.
/// </summary>
/// <param name="startElements">model elements to copy</param>
/// <param name="closureType"></param>
/// <returns></returns>
protected override ElementGroup CreateElementGroup(ICollection<ModelElement> startElements, ClosureType closureType)
{
// ElementClosureWalker finds all the connected elements,
// according to the propagate copy rules specified in the DSL Definition:
ElementClosureWalker walker = new ElementClosureWalker(this.Partition,
closureType, // Normally ClosureType.CopyClosure
startElements,
true, // Do not load other models.
null, // Optional list of domain roles not to traverse.
true); // Include relationship links where both ends are already included.
walker.Traverse(startElements);
IList<ModelElement> closureList = walker.ClosureList;
Dictionary<object, object> closureContext = walker.Context;
// create a group for this closure
ElementGroup group = new ElementGroup(this.Partition);
group.AddRange(closureList, false);
// create the element group prototype for the group
foreach (object key in closureContext.Keys)
{
group.SourceContext.ContextInfo[key] = closureContext[key];
}
return group;
}
}
}
Konten terkait
- Menyesuaikan Pembuatan dan Gerakan Elemen
- Cara: Menambahkan Penangan Seret dan Letakkan
- Sampel: Sampel Diagram Sirkuit VMSDK
Catatan
Komponen Transformasi Template Teks secara otomatis diinstal sebagai bagian dari beban kerja pengembangan ekstensi Visual Studio. Anda juga dapat menginstalnya dari tab Komponen individual Alat Penginstal Visual Studio, di bawah kategori SDK, pustaka, dan kerangka kerja. Instal komponen SDK Pemodelan dari tab Komponen individual.