Gestionnaires de modification de valeur de propriété de domaineDomain property value change handlers

Dans un langage spécifique à un domaine Visual StudioVisual Studio, quand la valeur d'une propriété de domaine change, les méthodes OnValueChanging() et OnValueChanged() sont appelées dans le gestionnaire de propriétés de domaine.In a Visual StudioVisual Studio domain-specific language, when the value of a domain property changes, the OnValueChanging() and OnValueChanged() methods are invoked in the domain property handler. Pour répondre au changement, vous pouvez substituer ces méthodes.To respond to the change, you can override these methods.

Substituer les méthodes de gestionnaire de propriétéOverride the Property Handler methods

Chaque propriété de domaine de votre langage spécifique à un domaine est gérée par une classe imbriquée dans sa classe de domaine parente.Each domain property of your domain-specific language is handled by a class that is nested inside its parent domain class. Son nom respecte le format PropertyNamePropertyHandler.Its name follows the format PropertyNamePropertyHandler. Vous pouvez examiner cette classe de gestionnaire de propriété dans le fichier Dsl\Generated Code\DomainClasses.cs.You can inspect this property handler class in the file Dsl\Generated Code\DomainClasses.cs. Dans la classe, OnValueChanging() est appelée juste avant que la valeur change et OnValueChanged() est appelée juste après que la valeur change.In the class, OnValueChanging() is called immediately before the value changes, and OnValueChanged() is called immediately after the value changes.

Par exemple, supposons que vous avez une classe de domaine nommée Comment qui a une propriété de domaine de chaîne nommée Text et une propriété entière nommé TextLengthCount.For example, suppose you have a domain class named Comment that has a string domain property named Text and an integer property named TextLengthCount. Pour provoquer le TextLengthCount toujours pour contenir la longueur de la Text chaîne, vous pouvez écrire le code suivant dans un fichier distinct dans le projet Dsl :To cause TextLengthCount always to contain the length of the Text string, you could write the following code in a separate file in the Dsl project:

// Domain Class "Comment":
public partial class Comment
{
  // Domain Property "Text":
  partial class TextPropertyHandler
  {
    protected override void OnValueChanging(CommentBase element, string oldValue, string newValue)
    {
      base.OnValueChanging(element, oldValue, newValue);

      // To update values outside the Store, write code here.

      // Let the transaction manager handle undo:
      Store store = element.Store;
      if (store.InUndoRedoOrRollback || store.InSerializationTransaction) return;

      // Update values in the Store:
      this.TextLengthCount = newValue.Length;
    }
  }
}

Notez les points suivants concernant les gestionnaires de propriétés :Notice the following points about property handlers:

  • Les méthodes de gestionnaires de propriétés sont appelées à la fois quand l'utilisateur modifie une propriété de domaine et quand du code de programme assigne une valeur différente à la propriété.The property handler methods are called both when the user makes changes to a domain property, and when program code assigns a different value to the property.

  • Les méthodes sont appelées uniquement quand la valeur change.The methods are called only when the value actually changes. Le gestionnaire n'est pas appelé si du code de programme assigne une valeur qui est égale à la valeur actuelle.The handler is not invoked if program code assigns a value that is equal to the current value.

  • Les propriétés de domaine de stockage personnalisées et calculées n'ont pas de méthodes OnValueChanged et OnValueChanging.Calculated and custom storage domain properties do not have OnValueChanged and OnValueChanging methods.

  • Vous ne pouvez pas utiliser un gestionnaire de modification pour modifier la nouvelle valeur.You cannot use a change handler to modify the new value. Pour cela, par exemple si vous souhaitez restreindre la valeur à une plage spécifique, définissez une ChangeRule.If you want to do that, for example to restrict the value to a particular range, define a ChangeRule.

  • Vous ne pouvez pas ajouter un gestionnaire de modification à une propriété qui représente un rôle d'une relation.You cannot add a change handler to a property that represents a role of a relationship. Au lieu de cela, définissez une AddRule et une DeleteRule sur la classe de relation.Instead, define an AddRule and a DeleteRule on the relationship class. Ces règles sont déclenchées quand les liens sont créés ou modifiés.These rules are triggered when the links are created or changed. Pour plus d’informations, consultez propager les modifications dans le modèle de règles.For more information, see Rules Propagate Changes Within the Model.

Modifications dans le magasinChanges in and out of the store

Les méthodes de gestionnaires de propriétés sont appelées dans la transaction ayant initié la modification.Property handler methods are called inside the transaction that initiated the change. Ainsi, vous pouvez apporter d'autres modifications dans le magasin sans ouvrir de nouvelle transaction.Therefore, you can make more changes in the store without opening a new transaction. Vos modifications peuvent avoir comme conséquence des appels de gestionnaires supplémentaires.Your changes might result in additional handler calls.

Quand une transaction est en cours d'annulation, de réexécution ou de restauration, vous ne devez pas modifier le magasin, c'est-à-dire ne pas modifier les éléments du modèle, relations, formes, connecteurs, diagrammes ou leurs propriétés.When a transaction is being undone, redone, or rolled back, you should not make changes in the store, that is, changes to model elements, relationships, shapes, connectors diagrams, or their properties.

De plus, vous ne devez généralement pas mettre des valeurs à jour quand le modèle est en cours de chargement à partir du fichier.Furthermore, you would usually not update values when the model is being loaded from the file.

Les modifications apportées au modèle doivent donc être protégées par un test tel que celui-ci :Changes to the model should therefore be guarded by a test like this:

if (!store.InUndoRedoOrRollback && !store. InSerializationTransaction)
{
   this.TextLength = ...; // in-store changes
}

En revanche, si votre gestionnaire de propriétés propage les modifications en dehors du magasin, par exemple vers un fichier, une base de données ou des variables en dehors du magasin, vous devez toujours apporter ces modifications pour que les valeurs externes soient mises à jour quand l'utilisateur effectue une annulation ou un rétablissement.By contrast, if your property handler propagates changes outside the store, for example, to a file, database, or non-store variables, then you should always make those changes so that the external values are updated when the user invokes undo or redo.

Annuler une modificationCancel a change

Si vous souhaitez empêcher une modification, vous pouvez rétablir la transaction actuelle.If you want to prevent a change, you can roll back the current transaction. Vous pourriez par exemple souhaiter vous assurer qu'une propriété demeure dans une plage spécifique.For example, you might want to ensure that a property remains within a specific range.

if (newValue > 10)
{
   store.TransactionManager.CurrentTransaction.Rollback();
   System.Windows.Forms.MessageBox.Show("Value must be less than 10");
}

Autre technique : propriétés calculéesAlternative technique: Calculated Properties

L'exemple précédent montre comment OnValueChanged() peut être utilisée pour propager des valeurs d'une propriété de domaine à une autre.The previous example shows how OnValueChanged() can be used to propagate values from one domain property to another. Chaque propriété a sa propre valeur stockée.Each property has its own stored value.

Au lieu de cela, vous pourriez définir la propriété dérivée en tant que propriété calculée.Instead, you could consider defining the derived property as a Calculated property. Dans ce cas, la propriété n'a aucun stockage propre et sa fonction de définition est évaluée chaque fois que sa valeur est nécessaire.In that case, the property has no storage of its own, and is defining function is evaluated whenever its value is required. Pour plus d’informations, consultez calculé et les propriétés de stockage personnalisé.For more information, see Calculated and Custom Storage Properties.

Au lieu de l’exemple précédent, vous pouvez définir le type champ TextLengthCount être calculée dans la définition DSL.Instead of the previous example, you could set the Kind field of TextLengthCount to be Calculated in the DSL Definition. Vous devez fournir votre propre obtenir méthode pour cette propriété de domaine.You would provide your own Get method for this domain property. Le obtenir méthode retourne la longueur actuelle de la Text chaîne.The Get method would return the current length of the Text string.

Toutefois, l'un des inconvénients potentiels des propriétés calculées est que l'expression est évaluée chaque fois que la valeur est utilisée, ce qui pourrait poser un problème de performance.However, a potential drawback of calculated properties is that the expression is evaluated every time the value is used, which might present a performance problem. De plus, il n'existe aucune méthode OnValueChanging() et OnValueChanged() sur une propriété calculée.Also, there is no OnValueChanging() and OnValueChanged() on a calculated property.

Autre technique : modifier les règlesAlternative technique: Change Rules

Si vous définissez un ChangeRule, elle est exécutée à la fin d’une transaction dans laquelle une valeur de propriété change.If you define a ChangeRule, it is executed at the end of a transaction in which a property's value changes. Pour plus d’informations, consultez propager les modifications dans le modèle de règles.For more information, see Rules Propagate Changes Within the Model.

Si plusieurs modifications sont apportées dans une même transaction, la ChangeRule s'exécute quand elles sont toutes terminées.If several changes are made in one transaction, the ChangeRule executes when they are all complete. En revanche, le OnValue... méthodes sont exécutées lorsque certaines modifications n’ont pas été effectuées.By contrast, the OnValue... methods are executed when some of the changes have not been performed. Selon le résultat souhaité, une ChangeRule pourrait être plus appropriée.Depending on what you want to achieve, this might make a ChangeRule more appropriate.

Vous pouvez également utiliser un ChangeRule pour ajuster la nouvelle valeur de la propriété pour qu’il soit dans une plage spécifique.You can also use a ChangeRule to adjust the property's new value to keep it within a specific range.

Avertissement

Si une règle modifie le contenu du magasin, d'autres règles et gestionnaires de propriétés peuvent être déclenchés.If a rule makes changes to the store content, other rules and property handlers might be triggered. Si une règle modifie la propriété qui l'a déclenchée, elle est de nouveau appelée.If a rule changes the property that triggered it, it will be called again. Vous devez vous assurer que vos définitions de règles ne provoquent pas un déclenchement sans fin.You must make sure that your rule definitions do not result in endless triggering.

using Microsoft.VisualStudio.Modeling;
...
// Change rule on the domain class Comment:
[RuleOn(typeof(Comment), FireTime = TimeToFire.TopLevelCommit)]
class MyCommentTrimRule : ChangeRule
{
  public override void
    ElementPropertyChanged(ElementPropertyChangedEventArgs e)
  {
    base.ElementPropertyChanged(e);
    Comment comment = e.ModelElement as Comment;

    if (comment.Text.StartsWith(" ") || comment.Text.EndsWith(" "))
      comment.Text = comment.Text.Trim();
    // If changed, rule will trigger again.
  }
}

// Register the rule:
public partial class MyDomainModel
{
 protected override Type[] GetCustomDomainModelTypes()
 { return new Type[] { typeof(MyCommentTrimRule) };
 }
}

ExempleExample

DescriptionDescription

L'exemple suivant substitue le gestionnaire de propriétés d'une propriété de domaine et informe l'utilisateur quand une propriété pour la classe de domaine ExampleElement a changé.The following example overrides the property handler of a domain property and notifies the user when a property for the ExampleElement domain class has changed.

CodeCode

using DslModeling = global::Microsoft.VisualStudio.Modeling;
using DslDesign = global::Microsoft.VisualStudio.Modeling.Design;

namespace msft.FieldChangeSample
{
  public partial class ExampleElement
  {
    internal sealed partial class NamePropertyHandler
    {
      protected override void OnValueChanged(ExampleElement element,
         string oldValue, string newValue)
      {
        if (!this.Store.InUndoRedoOrRollback)
        {
           // make in-store changes here...
        }
        // This part is called even in undo:
        System.Windows.Forms.MessageBox.Show("Value Has Changed");
        base.OnValueChanged(element, oldValue, newValue);
      }
    }
  }
}