Freigeben über


Regeln propagieren Änderungen im Modell

Sie können eine Speicherung die Regel erstellen, eine Änderung für ein Element zu anderen in der Visualisierung weiterzugeben und Modellieren SDK (VMSDK).Wenn eine Änderung an jedes Element im Speicher stattfindet, werden die Regeln ausgeführt werden, normalerweise geplant, wenn die äußerste Transaktion ein Commit ausgeführt wird.Es gibt verschiedene Typen von Regeln für verschiedene Arten von Ereignissen, beispielsweise das Hinzufügen eines Elements oder Löschen.Sie können Regeln auf bestimmte Typen von Elementen, Formen oder von Diagrammen verknüpfen.Viele integrierten Funktionen werden von Regeln definiert: Beispielsweise Regeln sichergestellt, dass ein Diagramm aktualisiert wird, wenn das Modell ändert.Sie können die domänenspezifische Sprache anpassen, indem Sie Regeln besitzen hinzufügen.

Weitergabe sind für die Regeln zum Speichern von Änderungen im Speicher, d. h. Änderungen an Modellelemente, Beziehungen, Formen und Konnektoren oder ihre Domäneneigenschaften hilfreich.Übergeben von Regeln nicht aus, wenn der Benutzer das Aufrufen von Befehlen Rückgängig- oder wiederholen.Stattdessen wird sichergestellt, dass die Belegung der Transaktions-Manager in den richtigen Zustand wiederhergestellt wird.Wenn Sie Änderungen an Ressourcen außerhalb des Arbeitsspeichers geben möchten, verwenden Sie Speicher-Ereignisse.Weitere Informationen finden Sie unter Ereignishandler propagieren Änderungen außerhalb des Modells.

Angenommen, Sie angeben möchten, dass, wenn der Benutzer (oder der Code) ein neues Element des Typs ExampleDomainClass erstellt, ein zusätzliches Element eines anderen Typs in einem anderen Teil des Modells erstellt wird.Sie können ein AddRule schreiben und sie mit ExampleDomainClass zuordnen.Sie können Code in der Regel zu erstellen, das zusätzliche Element geschrieben.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.Modeling;

namespace ExampleNamespace
{
 // Attribute associates the rule with a domain class:
 [RuleOn(typeof(ExampleDomainClass), FireTime=TimeToFire.TopLevelCommit)]
 // The rule is a class derived from one of the abstract rules:
 class MyAddRule : AddRule
 {
  // Override the abstract method:
  public override void ElementAdded(ElementAddedEventArgs e)
  {
    base.ElementAdded(e);
    ExampleDomainClass element = e.ModelElement;
    Store store = element.Store;
    // Ignore this call if we're currently loading a model:
    if (store.TransactionManager.CurrentTransaction.IsSerializing) 
       return;
    
    // Code here propagates change as required – for example:
      AnotherDomainClass echo = new AnotherDomainClass(element.Partition);
      echo.Name = element.Name;
      echo.Parent = element.Parent;  
    }
  }
 // The rule must be registered:
 public partial class ExampleDomainModel
 {
   protected override Type[] GetCustomDomainModelTypes()
   {
     List<Type> types = new List<Type>(base.GetCustomDomainModelTypes());
     types.Add(typeof(MyAddRule));
     // If you add more rules, list them here. 
     return types.ToArray();
   }
 }
}
HinweisHinweis

Der Code sollte den Zustand einer Regel nur von Elementen innerhalb des Speichers ändern. Das heißt, sollte die Regel nur von Modellelementen, Beziehungen, Formen, Konnektoren, Diagramme oder ihre Eigenschaften geändert werden.Wenn Sie Änderungen an Ressourcen außerhalb des Arbeitsspeichers geben möchten, definieren Sie Speicher-Ereignisse.Weitere Informationen finden Sie unter Ereignishandler propagieren Änderungen außerhalb des Modells

Um eine Regel definieren

  1. Definieren der Regel als Klasse, die mit dem RuleOn-Attribut vorangestellt wird.Das Attribut ordnet die Regel mit einem der Domänen Klassen, Beziehungen oder der Diagrammelemente zu.In der Regel wird für jede Instanz dieser Klasse angewendet, die möglicherweise abstrakt ist.

  2. Registrieren Sie die Regel, indem Sie diese in den Satz von GetCustomDomainModelTypes() hinzufügen im Domänenmodell - Klasse zurückgegeben wird.

  3. Leiten Sie die Klasse von einer der Regel abstrakten Klassen der Regel, und schreiben Sie den Code der Hinrichtungsmethode.

In den folgenden Abschnitten werden diese Schritte ausführlicher beschrieben.

Um eine Regel für eine Domänenklasse definieren

  • In einer benutzerdefinierten Codedatei definieren Sie eine Klasse und ein Präfix mit dem RuleOnAttribute-Attribut:

    [RuleOn(typeof(ExampleElement), 
         // Usual value – but required, because it is not the default:
         FireTime = TimeToFire.TopLevelCommit)] 
    class MyRule ...
    
  • Die abhängigen Typ in den ersten Parameter können eine Domänenklasse, ein Domänen-Verhältnis, eine Form, ein Konnektor oder ein Diagramm sein.Normalerweise aktivieren Sie Regeln für Domänen Klassen und verhältnisse an.

    FireTime ist normalerweise TopLevelCommit.Dadurch wird sichergestellt, dass der Regel nur schließlich die primären Änderungen der Transaktion vorgenommen worden sind.Die Alternativen sind Inline-, das die Regel bald nach der Änderung ausgeführt werden soll. LocalCommit und die Regel ausgeführt wird, das nach Abschluss der aktuellen Transaktion ist das äußerste (die möglicherweise nicht.)Sie können die Priorität einer Regel auch festlegen, deren Reihenfolge in der Warteschlange zu beeinflussen, dies ist jedoch eine unzuverlässige Methode des Erzielens des Ergebnisses, die Sie benötigen.

  • Sie können eine abstrakte Klasse angeben, wie der abhängige Typ.

  • In der Regel gilt für alle Instanzen der abhängigen Klasse.

  • Der Standardwert für FireTime ist TimeToFire.TopLevelCommit.Auf diese Weise werden die Regel ausgeführt wird, wenn die äußerste Transaktion ein Commit ausgeführt wird.Eine Alternative besteht darin TimeToFire.Inline.Auf diese Weise werden die Regel bald nach dem auslösenden Ereignis ausgeführt werden.

Um die Regel registrieren

  • Fügen Sie der Klasse die Regel Liste von Typen hinzu, die von GetCustomDomainModelTypes im Domänenmodell zurückgegeben werden:

    public partial class ExampleDomainModel
     {
       protected override Type[] GetCustomDomainModelTypes()
       {
         List<Type> types = new List<Type>(base.GetCustomDomainModelTypes());
         types.Add(typeof(MyAddRule));
         // If you add more rules, list them here. 
         return types.ToArray();
       }
     }
    
  • Wenn Sie nicht den Namen der Domänenmodell Klasse sicher sind, finden Sie in der Datei Dsl\GeneratedCode\DomainModel.cs

  • Schreiben Sie diesen Code in einer benutzerdefinierten Codedatei im DSL-Projekt.

So führen Sie den Code schreiben. d. R.

  • Leiten Sie die Klasse von einer der Regel folgenden Basisklassen:

    Basisklasse

    Trigger

    AddRule

    Ein Element, ein Link oder ein Formular hinzugefügt wird.

    Verwenden Sie dies, um neue Beziehungen, zusätzlich zu den neuen Elementen zu erkennen.

    ChangeRule

    Ein Wert Domäneneigenschaften geändert wird.Das Methodenargument stellt die alten und neuen Werte.

    Für Forms wird diese Regel ausgelöst, wenn die integrierten AbsoluteBounds-Eigenschaft ändert, wenn die Form verschoben wird.

    In vielen Fällen ist es einfacher, OnValueChanged oder OnValueChanging im Handler Eigenschaft zu überschreiben.Diese Methode wird unmittelbar vor und nach der Änderung aufgerufen.Im Gegensatz dazu wird die Regel normalerweise am Ende der Transaktion ausgeführt.Weitere Informationen finden Sie unter Handler für Wertänderungen von Domäneneigenschaften.

    HinweisHinweis
    Diese Regel wird ausgelöst, wenn ein Link erstellt oder gelöscht wird.Schreiben Sie stattdessen AddRule und DeleteRule für das Domänen-Verhältnis.

    DeletingRule

    Gestartet, wenn ein Element oder ein Link gerade gelöscht werden sollen.Die Eigenschaft gilt ModelElement.IsDeleting bis zum Ende der Transaktion.

    DeleteRule

    Ausgeführt, wenn ein Element oder ein Link gelöscht wurde.Der Regel wird schließlich andere Regeln ausgeführt worden sind, einschließlich DeletingRules ausgeführt.ModelElement.IsDeleting ist ungültig; ModelElement.IsDeleted ist true.Um ein nachfolgendes Rückgängig zu ermöglichen, wird das Element nicht aus dem Arbeitsspeicher entfernt, sondern es wird von Store.ElementDirectory entfernt.

    MoveRule

    Ein Element wird aus einer Speicher partition in einen anderen verschoben.

    (Beachten Sie, dass dies nicht der grafischen Position einer Form) verknüpft ist.

    RolePlayerChangeRule

    Diese Regel gilt nur für Domänen-Verhältnisse.Sie wird gestartet, wenn Sie nicht ausdrücklich ein Modellelement an beiden Enden eines Links zuweisen.

    RolePlayerPositionChangeRule

    Gestartet, wenn die Reihenfolge von Links in einen oder aus einem Element mithilfe der Methoden MoveBefore oder MoveToIndex auf einen Link geändert wird.

    TransactionBeginningRule

    Ausgeführt, wenn eine Transaktion erstellt wird.

    TransactionCommittingRule

    Ausgeführt, wenn die Transaktion ein Commit ausgeführt werden soll.

    TransactionRollingBackRule

    Ausgeführt, wenn die Transaktion zurücksetzen.

  • Jede Klasse verfügt über eine Methode, die überschrieben.Geben Sie override in der Klasse, um sie zu ermitteln.Der Parameter dieser Methode bezeichnet das Element, das geändert wurde.

Beachten Sie die folgenden Punkte zu Regeln:

  1. Der Satz von Änderungen in einer Transaktion, die möglicherweise zahlreiche Regeln.Normalerweise werden die Regeln ausgeführt, wenn die äußerste Transaktion ein Commit ausgeführt wird.Sie werden in einer nicht angegebenen Reihenfolge ausgeführt.

  2. Eine Regel wird immer innerhalb einer Transaktion ausgeführt.Deshalb müssen Sie eine neue Transaktion erstellt werden, um Änderungen vorzunehmen.

  3. Die Regeln werden nicht ausgeführt, wenn eine Transaktion zurückgesetzt wird, oder wenn der Rückgängig- oder Wiederholungsvorgänge ausgeführt werden.Diese Operationen setzen den gesamten Inhalt des Arbeitsspeichers auf den vorherigen Zustand zurück.Wenn die Regel den Zustand aller außerhalb des Speichers geändert wird, hält möglicherweise nicht im Synchronismus mit dem Speicher Inhalt.Um Zustand außerhalb des Arbeitsspeichers zu aktualisieren, ist es besser Ereignisse zu verwenden.Weitere Informationen finden Sie unter Ereignishandler propagieren Änderungen außerhalb des Modells.

  4. Einige Regeln werden ausgeführt, wenn ein Modell aus Datei geladen wird.Um zu bestimmen, ob das Speichern oder Laden noch ausgeführt wird, verwenden Sie store.TransactionManager.CurrentTransaction.IsSerializing.

  5. Wenn der Code der Regel mehr Regel " erstellt, werden sie am Ende der Liste hinzugefügt und Auslösen ausgeführt werden, bevor die Transaktion abgeschlossen ist.DeletedRules werden schließlich andere Regeln ausgeführt.Eine Regel kann mehrfach in einer Transaktion einmal für jede Änderung ausführen.

  6. Um Daten in und von Regeln zu übergeben, können Sie Informationen in TransactionContextspeichern.Dies ist nur ein Wörterbuch, das während der Transaktion gewartet wird.Er wird freigegeben, wenn die Transaktion abgeschlossen ist.Die Ereignisargumente für jede Regel bieten Zugriff darauf.Denken Sie daran, dass Regeln nicht auf vorhersehbare Reihenfolge ausgeführt werden.

  7. Verwenden Sie nach der Regeln für die Beachtung andere Alternativen.Wenn Sie beispielsweise eine Eigenschaft aktualisieren möchten, wenn sich ein Wert ändert, erwägen, eine berechnete Eigenschaft verwendet werden kann.Wenn Sie die Größe oder Position einer Form einschränken möchten, verwenden Sie BoundsRule.Wenn Sie auf eine Änderung eines Eigenschaftswerts reagieren möchten, fügen Sie einen OnValueChanged-Handler der Eigenschaft hinzu.Weitere Informationen finden Sie unter Reagieren auf und Propagieren von Änderungen.

Beispiel

Das folgende Beispiel aktualisiert eine Eigenschaft, wenn ein Domänen-Verhältnis instanziiert wird, um zwei Elementen zu verknüpfen.In der Regel wird ausgelöst, wenn der Benutzer nicht nur eine Verbindung in einem Diagramm erstellen, sondern auch, wenn Programmcode eine Verbindung erstellt wird.

Um dieses Beispiel zu testen, erstellen Sie ein DSL mit der Vorlage für Office-Projektmappen Aufgaben-Fluss, und fügen Sie den folgenden Code in einer Datei im Dsl-Projekt ein.Erstellen Sie die Projektmappe, und führen Sie sie aus, und öffnen Sie die Beispieldatei Debuggen im Projekt.Zeichnen eines Kommentar-Link zwischen einem Kommentarshape und einem Flusselement.Der Text des Kommentars geändert werden, um über das letzte Element zu melden, dass Sie eine Verbindung hergestellt haben.

In der Praxis verwenden Sie normalerweise ein DeleteRule für jedes AddRule schreiben.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Modeling;

namespace Company.TaskRuleExample
{

  [RuleOn(typeof(CommentReferencesSubjects))]
  public class RoleRule : AddRule
  {

    public override void ElementAdded(ElementAddedEventArgs e)
    {
      base.ElementAdded(e);
      CommentReferencesSubjects link = e.ModelElement as CommentReferencesSubjects;
      Comment comment = link.Comment;
      FlowElement subject = link.Subject;
      Transaction current = link.Store.TransactionManager.CurrentTransaction;
      // Don't want to run when we're just loading from file:
      if (current.IsSerializing) return;
      comment.Text = "Flow has " + subject.FlowTo.Count + " outgoing connections";
    }
    
  }

  public partial class TaskRuleExampleDomainModel
  {
    protected override Type[] GetCustomDomainModelTypes()
    {
      List<Type> types = new List<Type>(base.GetCustomDomainModelTypes());
      types.Add(typeof(RoleRule));
      return types.ToArray();
    }
  }

}

Siehe auch

Konzepte

Ereignishandler propagieren Änderungen außerhalb des Modells

BoundsRules schränken Position und Größe von Formen ein