Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Model öğelerini oluşturmak ve silmek, özelliklerini ayarlamak ve öğeler arasında bağlantılar oluşturup silmek için kod yazabilirsiniz. Tüm değişiklikler bir işlem içinde yapılmalıdır. Öğeler diyagramda görüntüleniyorsa, diyagram işlemin sonunda otomatik olarak "düzeltilir".
Örnek DSL Tanımı
Bu konu başlığı altındaki örnekler için DslDefinition.dsl dosyasının ana bölümü budur:
Bu model, bu DSL'nin bir örneğidir:
Referanslar ve Ad Alanları
Bu konudaki kodu çalıştırmak için aşağıdakilere başvurmanız gerekir:
Microsoft.VisualStudio.Modeling.Sdk.11.0.dll
Kodunuz şu ad alanını kullanır:
using Microsoft.VisualStudio.Modeling;
Ayrıca, kodu DSL'nizin tanımlandığı projeden farklı bir projede yazıyorsanız, DSL projesi tarafından oluşturulan derlemeyi içeri aktarmanız gerekir.
Modelde Navigasyon
Özellikler
DSL tanımında tanımladığınız etki alanı özellikleri, program kodunda erişebileceğiniz özelliklere dönüşür:
Person henry = ...;
if (henry.BirthDate < 1500) ...
if (henry.Name.EndsWith("VIII")) ...
Bir özellik ayarlamak istiyorsanız, bunu bir işlem içinde yapmanız gerekir:
henry.Name = "Henry VIII";
DSL tanımında bir özelliğin Kind'iHesaplanmış ise, bunu ayarlayamazsınız. Daha fazla bilgi için bkz. Hesaplanan ve Özel Depolama Özellikleri.
Ilişki
DSL tanımında etki alanı ilişkileri tanımladığınızda, bunlar ilişkinin her iki ucundaki sınıflarda birer özellik çifti oluşturur. Özelliklerin adları DslDefinition diyagramında ilişkinin her tarafındaki rollerde etiketler olarak görünür. Rolün çokluğuna bağlı olarak, özelliğin türü ilişkinin diğer ucundaki sınıf veya bu sınıfın koleksiyonudur.
foreach (Person child in henry.Children) { ... }
FamilyTreeModel ftree = henry.FamilyTreeModel;
İlişkinin karşı uçlarında yer alan özellikler her zaman karşılıklıdır. Bir bağlantı oluşturulduğunda veya silindiğinde, her iki öğedeki rol özellikleri de güncelleştirilir. Aşağıdaki ifade (hangi System.Linq uzantılarını kullanırsa kullansın), örnekteki ParentsHaveChildren ilişkisi için her zaman doğrudur.
(Person p) => p.Children.All(child => child.Parents.Contains(p))
&& p.Parents.All(parent => parent.Children.Contains(p));
ElementLinks. İlişki, etki alanı ilişki türünün bir örneği olan bağlantı adlı model öğesiyle de temsil edilir. Bağlantının her zaman bir kaynak öğesi ve bir hedef öğesi vardır. Kaynak öğe ve hedef öğe aynı olabilir.
Bağlantıya ve özelliklerine erişebilirsiniz:
ParentsHaveChildren link = ParentsHaveChildren.GetLink(henry, edward);
// This is now true:
link == null || link.Parent == henry && link.Child == edward
Varsayılan olarak, bir ilişkinin birden fazla örneğinin herhangi bir model öğesi çiftini bağlamasına izin verilmez. Ancak DSL tanımında, ilişki için Allow Duplicates bayrağı doğruysa, birden fazla bağlantı olabilir ve GetLinks kullanmanız gerekebilir.
foreach (ParentsHaveChildren link in ParentsHaveChildren.GetLinks(henry, edward)) { ... }
Bağlantılara erişmek için başka yöntemler de vardır. Örneğin:
foreach (ParentsHaveChildren link in ParentsHaveChildren.GetLinksToChildren(henry)) { ... }
Gizli roller. DSL tanımında, Belirli bir rol için Oluşturulan ÖzellikYanlış ise, o role karşılık gelen hiçbir özellik oluşturulmaz. Ancak, yine de bağlantılara erişebilir ve ilişkinin yöntemlerini kullanarak bağlantılarda geçiş yapabilirsiniz:
foreach (Person p in ParentsHaveChildren.GetChildren(henry)) { ... }
En sık kullanılan örnek, bir model öğesini diyagramda görüntüleyen şekle bağlayan ilişkidir PresentationViewsSubject :
PresentationViewsSubject.GetPresentation(henry)[0] as PersonShape
Öğe Dizini
öğe dizinini kullanarak depodaki tüm öğelere erişebilirsiniz:
store.ElementDirectory.AllElements
Öğeleri bulmak için aşağıdakiler gibi yöntemler de vardır:
store.ElementDirectory.FindElements(Person.DomainClassId);
store.ElementDirectory.GetElement(elementId);
Sınıf Bilgilerine Erişme
DSL tanımının sınıfları, ilişkileri ve diğer yönleri hakkında bilgi alabilirsiniz. Örneğin:
DomainClassInfo personClass = henry.GetDomainClass();
DomainPropertyInfo birthProperty =
personClass.FindDomainProperty("BirthDate")
DomainRelationshipInfo relationship =
link.GetDomainRelationship();
DomainRoleInfo sourceRole = relationship.DomainRole[0];
Model öğelerinin üst sınıfları aşağıdaki gibidir:
ModelElement - tüm öğeler ve ilişkiler ModelElement'lerdir
ElementLink - tüm ilişkiler ElementLink'lerdir
İşlem İçinde Değişiklik Yapma
Program kodunuz Mağaza'daki herhangi bir şeyi değiştirdiğinden, bunu bir işlem içinde yapması gerekir. Bu, tüm model öğeleri, ilişkiler, şekiller, diyagramlar ve bunların özellikleri için geçerlidir. Daha fazla bilgi için bkz. Transaction.
Bir işlemi yönetmenin en uygun yolu, bir try...catch deyimi içine alınmış using deyimidir.
Store store; ...
try
{
using (Transaction transaction =
store.TransactionManager.BeginTransaction("update model"))
// Outermost transaction must always have a name.
{
// Make several changes in Store:
Person p = new Person(store);
p.FamilyTreeModel = familyTree;
p.Name = "Edward VI";
// end of changes to Store
transaction.Commit(); // Don't forget this!
} // transaction disposed here
}
catch (Exception ex)
{
// If an exception occurs, the Store will be
// rolled back to its previous state.
}
Bir işlem içinde istediğiniz sayıda değişiklik yapabilirsiniz. Etkin bir işlem içinde yeni işlemler açabilirsiniz.
Değişikliklerinizi kalıcı hale getirmek için, atılmadan önce işlemi onaylamanız gerekir Commit. İşlem içinde yakalanmayan bir istisna oluşursa, Depo değişikliklerden önceki durumuna sıfırlanır.
Model Öğeleri Oluşturma
Bu örnek, mevcut modele bir öğe ekler:
FamilyTreeModel familyTree = ...; // The root of the model.
using (Transaction t =
familyTree.Store.TransactionManager
.BeginTransaction("update model"))
{
// Create a new model element
// in the same partition as the model root:
Person edward = new Person(familyTree.Partition);
// Set its embedding relationship:
edward.FamilyTreeModel = familyTree;
// same as: familyTree.People.Add(edward);
// Set its properties:
edward.Name = "Edward VII";
t.Commit(); // Don't forget this!
}
Bu örnekte, öğe oluşturmayla ilgili şu temel noktalar gösterilmektedir:
Yeni öğeyi Mağaza'nın belirli bir bölümünde oluşturun. Model öğeleri ve ilişkiler için, ancak şekiller için değil, bu genellikle varsayılan bölümdür.
Ekleme ilişkisinin hedefi haline getirin. Bu örneğin DslDefinition bölümünde her Kişi FamilyTreeHasPeople ilişkisini eklemenin hedefi olmalıdır. Bunu başarmak için, Person nesnesinin FamilyTreeModel rol özelliğini ayarlayabilir veya Kişi'yi FamilyTreeModel nesnesinin Kişiler rol özelliğine ekleyebiliriz.
Yeni bir öğenin özelliklerini ayarlayın, özellikle DslDefinition'da true olan özelliği
IsNameolacak şekilde dikkatlice yapılandırın. Bu bayrak, bir ögenin kendi sahibinin içinde benzersiz olarak tanımlanmasını sağlayan özelliği belirtir. Bu durumda Name özelliğinde bu bayrak bulunur.Bu DSL'nin DSL tanımı Mağaza'ya yüklenmiş olmalıdır. Menü komutu gibi bir uzantı yazıyorsanız, bu genellikle zaten doğru olacaktır. Diğer durumlarda, modeli mağazaya açıkça yükleyebilir veya model yüklemek için ModelBus kullanabilirsiniz. Daha fazla bilgi için bkz . Nasıl yapılır: Program Kodunda Dosyadan Model Açma.
Bu şekilde bir öğe oluşturduğunuzda, otomatik olarak bir şekil oluşturulur (DSL'nin diyagramı varsa). Varsayılan şekil, renk ve diğer özelliklerle otomatik olarak atanan bir konumda görünür. İlişkili şeklin nerede ve nasıl görüneceğini denetlemek istiyorsanız bkz. Öğe oluşturma ve şekli.
İlişki Bağlantıları Oluşturma
Örnek DSL tanımında tanımlanan iki ilişki vardır. Her ilişki, ilişkinin her sonundaki sınıfta bir rol özelliği tanımlar.
bir ilişkinin örneğini oluşturmanın üç yolu vardır. Bu üç yöntemin her biri aynı etkiye sahiptir:
Kaynak rol oynatıcının özelliğini ayarlayın. Örneğin:
familyTree.People.Add(edward);edward.Parents.Add(henry);
Hedef rol oynatıcının özelliğini ayarlayın. Örneğin:
edward.familyTreeModel = familyTree;Bu rolün çokluğudur
1..1, bu nedenle değeri atarız.henry.Children.Add(edward);Bu rolün çokluk değeri
0..*olduğundan, koleksiyona ekliyoruz.
İlişkinin bir örneğini açıkça oluşturun. Örneğin:
FamilyTreeHasPeople edwardLink = new FamilyTreeHasPeople(familyTreeModel, edward);ParentsHaveChildren edwardHenryLink = new ParentsHaveChildren(henry, edward);
Son yöntem, ilişkinin kendisinde özellikleri ayarlamak istiyorsanız kullanışlıdır.
Bu şekilde bir öğe oluşturduğunuzda, diyagramdaki bir bağlayıcı otomatik olarak oluşturulur, ancak varsayılan bir şekil, renk ve diğer özelliklere sahiptir. İlişkili bağlayıcının nasıl oluşturulduğunu denetlemek için bkz. Öğe ve Şekil Oluşturma.
Öğeleri Silme
Öğeyi silmek için Delete() çağırarak bir öğeyi silin.
henry.Delete();
Bu işlem şunları da siler:
Öğeye ve öğeden ilişki bağlantıları. Örneğin,
edward.Parentsartık içermeyecektirhenry.PropagatesDeletebayrağının true olduğu rollerdeki öğeler. Örneğin, öğesini görüntüleyen şekil silinir.
Varsayılan olarak, her ekleme ilişkisinin hedef rolünde PropagatesDelete true değeri vardır.
henry öğesini silmek, familyTree öğesini silmez. Ancak, familyTree.Delete() tüm Persons öğesini siler.
Varsayılan olarak, PropagatesDelete başvuru ilişkilerinin rolleri için doğru değildir.
Bir nesneyi sildiğinizde, silme kurallarının belirli bulaşmaları göz ardı etmesine neden olabilirsiniz. Bu, bir öğeyi başka bir öğe için değiştiriyorsanız kullanışlıdır. Silme işleminin yayılmaması gereken bir veya daha fazla rolün GUID'sini sağlarsınız. GUID, ilişki sınıfından alınabilir:
henry.Delete(ParentsHaveChildren.SourceDomainRoleId);
(Çünkü PropagatesDelete ilişkisi, ParentsHaveChildren ilişkisindeki roller için false olduğundan, bu özel örneğin hiçbir etkisi olmaz.)
Bazı durumlarda silme işlemi, öğede veya yayma tarafından silinecek bir öğede bir kilidin bulunmasıyla engellenir. öğesinin silinip silinemeyeceğini denetlemek için kullanabilirsiniz element.CanDelete() .
İlişki Bağlantılarını Silme
Bir öğeyi rol özelliğinden kaldırarak ilişki bağlantısını silebilirsiniz:
henry.Children.Remove(edward); // or:
edward.Parents.Remove(henry); // or:
Ayrıca bağlantıyı açıkça silebilirsiniz:
edwardHenryLink.Delete();
Bu üç yöntemin tümü aynı etkiye sahiptir. Bunlardan yalnızca birini kullanmanız gerekir.
Rolün 0..1 veya 1..1 çokluğu varsa, bunu nullolarak veya başka bir değere ayarlayabilirsiniz:
edward.FamilyTreeModel = null; veya:
edward.FamilyTreeModel = anotherFamilyTree;
bir İlişkinin Bağlantılarını Yeniden Sıralama
Belirli bir model öğesinde kaynaklanan veya hedeflenen belirli bir ilişkinin bağlantıları belirli bir diziye sahiptir. Eklendikleri sırada görünürler. Örneğin, bu ifade her zaman alt ögeleri aynı sırada verir:
foreach (Person child in henry.Children) ...
Bağlantıların sırasını değiştirebilirsiniz:
ParentsHaveChildren link = GetLink(henry,edward);
ParentsHaveChildren nextLink = GetLink(henry, elizabeth);
DomainRoleInfo role =
link.GetDomainRelationship().DomainRoles[0];
link.MoveBefore(role, nextLink);
Locks
Değişiklikleriniz bir kilit tarafından engellenebilir. Kilitler tek tek öğelerde, bölümlerde ve depolama alanında ayarlanabilir. Yapmak istediğiniz değişiklik türünü engelleyen bir kilit bu düzeylerden herhangi birinde varsa, bunu denediğinizde bir istisna fırlatılabilir. Kilitlerin ayarlanıp ayarlanmadığını anlamak için, ad alanı Microsoft.VisualStudio.Modeling.Immutability içinde tanımlanan bir uzantı yöntemi olan element.GetLocks() kullanılabilir.
Daha fazla bilgi için bkz. Read-Only Segmentleri Oluşturmak için Kilitleme İlkesi Tanımlama.
Kopyala ve Yapıştır
Öğeleri veya öğe gruplarını IDataObject'a kopyalayabilirsiniz:
Person person = personShape.ModelElement as Person;
Person adopter = adopterShape.ModelElement as Person;
IDataObject data = new DataObject();
personShape.Diagram.ElementOperations
.Copy(data, person.Children.ToList<ModelElement>());
Öğeler serileştirilmiş Öğe Grubu olarak depolanır.
Bir IDataObject öğesindeki öğeleri bir modelle birleştirebilirsiniz:
using (Transaction t = targetDiagram.Store.
TransactionManager.BeginTransaction("paste"))
{
adopterShape.Diagram.ElementOperations.Merge(adopter, data);
}
Merge () ya bir PresentationElement ya da bir ModelElement kabul edebilir. Bir verirseniz PresentationElement, hedef diyagramda üçüncü parametre olarak bir konum da belirtebilirsiniz.
Diyagramlarda gezinme ve diyagramları güncelleştirme
DSL'de, Person veya Song gibi bir kavramı temsil eden etki alanı modeli öğesi, diyagramda gördüklerinizi temsil eden şekil öğesinden ayrıdır. Etki alanı modeli öğesi, kavramların önemli özelliklerini ve ilişkilerini depolar. Şekil öğesi diyagramda nesne görünümünün boyutunu, konumunu ve rengini ve bileşen parçalarının düzenini depolar.
Sunu Öğeleri
DSL Tanımınızda, belirttiğiniz her öğe aşağıdaki standart sınıflardan birinden türetilen bir sınıf oluşturur.
| Öğe türü | Temel sınıf |
|---|---|
| Etki alanı sınıfı | ModelElement |
| Etki alanı ilişkisi | ElementLink |
| Shape | NodeShape |
| Connector | BinaryLinkShape |
| Diagram | Diagram |
Diyagramdaki bir öğe genellikle bir model öğesini temsil eder. Genellikle (ancak her zaman değil), bir NodeShape etki alanı sınıfı örneğini ve bir BinaryLinkShape etki alanı ilişki örneğini temsil eder. İlişki, PresentationViewsSubject bir düğüm veya bağlantı şeklini temsil ettiği model öğesine bağlar.
Her düğüm veya bağlantı şekli bir diyagrama aittir. İkili bağlantı şekli iki düğüm şeklini bağlar.
Şekiller, iki kümede alt şekiller barındırabilir. Kümedeki NestedChildShapes bir şekil, üst öğesinin sınırlayıcı kutusuyla sınırlandırılır. Listedeki RelativeChildShapes şekil, ana öğe sınırlarının tamamen ya da kısmen dışında, örneğin bir etiket veya bağlantı noktası olarak, görünebilir. Diyagramda RelativeChildShapes ve Parent yoktur.
Şekiller ve öğeler arasında gezinme
Alan modeli öğeleri ve şekil öğeleri PresentationViewsSubject ile ilişkilidir.
// using Microsoft.VisualStudio.Modeling;
// using Microsoft.VisualStudio.Modeling.Diagrams;
// using System.Linq;
Person henry = ...;
PersonShape henryShape =
PresentationViewsSubject.GetPresentation(henry)
.FirstOrDefault() as PersonShape;
Aynı ilişki, ilişkileri diyagramdaki bağlayıcılara bağlar:
Descendants link = Descendants.GetLink(henry, edward);
DescendantConnector dc =
PresentationViewsSubject.GetPresentation(link)
.FirstOrDefault() as DescendantConnector;
// dc.FromShape == henryShape && dc.ToShape == edwardShape
Bu ilişki ayrıca modelin kökünü diyagrama bağlar:
FamilyTreeDiagram diagram =
PresentationViewsSubject.GetPresentation(familyTree)
.FirstOrDefault() as FamilyTreeDiagram;
Bir şekille temsil edilen model öğesini almak için şunu kullanın:
henryShape.ModelElement as Person
diagram.ModelElement as FamilyTreeModel
Diyagramda gezinme
Genel olarak diyagramdaki şekiller ve bağlayıcılar arasında gezinmek önerilmez. Modeldeki ilişkilerde gezinmek, şekiller ve bağlayıcılar arasında yalnızca diyagramın görünümü üzerinde çalışmak gerektiğinde gezinmek daha iyidir. Bu yöntemler bağlayıcıları her uçta şekillere bağlar:
personShape.FromRoleLinkShapes, personShape.ToRoleLinkShapes
connector.FromShape, connector.ToShape
Birçok şekil bileşiktir; bir ana şekil ve bir veya daha fazla alt katmandan oluşur. Başka bir şekle göre konumlandırılan şekillerin alt öğeleri olduğu söylenir. Üst şekil hareket ettiğinde, alt öğeler de onunla birlikte hareket eder.
Göreli alt öğeler ebeveyn şeklin sınırlayıcı kutusunun dışında görünebilir. İç içe geçmiş alt öğeler, kesinlikle üst öğe sınırlarının içinde görünür.
Diyagramdaki en üst şekil kümesini elde etmek için şunu kullanın:
Diagram.NestedChildShapes
Şekillerin ve bağlayıcıların ata sınıfları şunlardır:
-- ShapeElement
----- NodeShape
------- Diagram
------- Şekliniz
----- LinkShape
------- BinaryLinkShape
--------- YourConnector
Şekillerin ve Bağlayıcıların Özellikleri
Çoğu durumda, şekillerde açık değişiklikler yapmak gerekli değildir. Model öğelerini değiştirdiğinizde, "düzeltme" kuralları şekilleri ve bağlayıcıları güncelleştirir. Daha fazla bilgi için bkz. Değişiklikleri Yanıtlama ve Yayma.
Ancak, model öğelerinden bağımsız özelliklerdeki şekillerde bazı açık değişiklikler yapmak yararlıdır. Örneğin, şu özellikleri değiştirebilirsiniz:
Size - şeklin yüksekliğini ve genişliğini belirler.
Location - ebeveyn şekle veya diyagrama göre konum
StyleSet - şekli veya bağlayıcıyı çizmek için kullanılan kalem ve fırça kümesi
Hide - şekli görünmez yapar
Show - bir
Hide()sonra şekli görünür hale getirir.
Öğe ve Şekli Oluşturma
Bir öğe oluşturduğunuzda ve bu öğeyi ilişkileri ekleme ağacına bağladığınızda, şekil otomatik olarak oluşturulur ve onunla ilişkilendirilir. Bu işlem, işlemin tamamlanmasının ardından yürütülen "düzeltme" kuralları tarafından gerçekleştirilir. Ancak, şekil otomatik olarak atanan bir konumda görünür ve şekli, rengi ve diğer özellikleri varsayılan değerlere sahip olur. Şeklin nasıl oluşturulduğunu denetlemek için birleştirme işlevini kullanabilirsiniz. Önce bir ElementGroup'a eklemek istediğiniz öğeleri eklemeniz ve ardından grubu diyagramda birleştirmeniz gerekir.
Bu yöntem:
Öğe adı olarak bir özellik atadıysanız adı ayarlar.
DSL Tanımında belirttiğiniz tüm Öğe Birleştirme Yönergelerini gözlemler.
Bu örnek, kullanıcı diyagrama çift tıkladığında fare konumunda bir şekil oluşturur. Bu örnek için DSL Tanımında FillColor özelliği ExampleShape görünür hale getirildi.
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
partial class MyDiagram
{
public override void OnDoubleClick(DiagramPointEventArgs e)
{
base.OnDoubleClick(e);
using (Transaction t = this.Store.TransactionManager
.BeginTransaction("double click"))
{
ExampleElement element = new ExampleElement(this.Store);
ElementGroup group = new ElementGroup(element);
{ // To use a shape of a default size and color, omit this block.
ExampleShape shape = new ExampleShape(this.Partition);
shape.ModelElement = element;
shape.AbsoluteBounds = new RectangleD(0, 0, 1.5, 1.0);
shape.FillColor = System.Drawing.Color.Azure;
group.Add(shape);
}
this.ElementOperations.MergeElementGroupPrototype(
this,
group.CreatePrototype(),
PointD.ToPointF(e.MousePosition));
t.Commit();
}
}
}
Birden fazla şekil sağlarsanız, AbsoluteBounds kullanarak onların göreli konumlarını ayarlayın.
Bu yöntemi kullanarak bağlayıcıların rengini ve diğer kullanıma sunulan özelliklerini de ayarlayabilirsiniz.
İşlem Kullanımı
Şekiller, bağlayıcılar ve diyagramlar, ModelElement'ın alt türleridir ve Mağaza'da bulunur. Bu nedenle, bu işlemlerde yalnızca bir işlem içinde değişiklik yapmanız gerekir. Daha fazla bilgi için bkz . Nasıl yapılır: Modeli Güncelleştirmek için İşlemleri Kullanma.
Belge Görünümü ve Belge Verileri
Bölümleri Depola
Bir model yüklendiğinde, eşlik eden diyagram aynı anda yüklenir. Genellikle model Store.DefaultPartition'a yüklenir ve diyagram içeriği başka bir Bölüme yüklenir. Genellikle her bölümün içeriği yüklenir ve ayrı bir dosyaya kaydedilir.