共用方式為


網域屬性值變更處理常式

在Visual Studio定義域專屬語言中,當網域屬性的值變更時, OnValueChanging()和OnValueChanged()網域屬性處理常式中叫用方法。若要回應變更,您可以覆寫這些方法。

覆寫屬性處理常式方法

在其父網域類別為巢狀類別會處理定義域專屬語言的每個網域內容。它的名稱遵循格式 PropertyNamePropertyHandler。您可以檢查這個檔案中的屬性處理常式類別Dsl\Generated Code\DomainClasses.cs。在類別中, OnValueChanging()呼叫之前的值變更,以及OnValueChanged()的值變更之後立即被呼叫。

比方說,假設您有一個網域類別名為註解 ,具有字串網域名為 文字 和整數屬性名稱為 TextLengthCount。若要引發 TextLengthCount 一定要包含的長度文字字串,您可以在不同的檔案,Dsl 專案中撰寫下列程式碼:

  // 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;
      }
    }
  }

請注意下列幾點相關屬性處理常式:

  • 使用者對 [網域] 屬性中,變更和程式碼會將不同的值指派給屬性時,會呼叫的屬性處理常式方法。

  • 實際變更值時才呼叫的方法。如果程式碼將指派的值,相當於目前的值,不會叫用處理常式。

  • 計算及自訂儲存網域內容並沒有 OnValueChanged 和 OnValueChanging 方法。

  • 您無法使用變更處理常式,來修改新的值。如果您想要這樣做,例如限制到特定範圍的值會定義ChangeRule。

  • 您無法將變更的處理常式加入屬性表示關聯性的角色。相反地,定義AddRule和DeleteRule上的關聯性類別。當建立或變更連結時,便會觸發這些規則。如需詳細資訊,請參閱規則傳播模型內的變更

Bb126481.collapse_all(zh-tw,VS.110).gif在儲存區及淡出的變更

在起始變更的交易內,稱為屬性處理常式方法。因此,您可以進行存放區中的更多的變更,而不必開啟新的交易。您的變更可能會造成額外的處理常式呼叫。

交易已被復原了,當取消復原,或復原交易,請勿進行的變更在存放區,也就是變更為模型項目、 關聯性、 圖形、 連接器圖表或其屬性。

此外,您會通常未更新值從檔案載入模型時。

模型的變更因此應該保護這類測試:

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

相較之下,如果您的屬性處理常式將存放區外的變更,比方說,至檔案、 資料庫或非存放區變數,然後您應該一律進行這些變更,使外部的值會更新使用者叫用 [復原或取消復原。

Bb126481.collapse_all(zh-tw,VS.110).gif取消變更

若要防止變更,您可以還原目前的交易。例如,您可以確保屬性一定會在特定範圍內。

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

Bb126481.collapse_all(zh-tw,VS.110).gif另一個技術: 計算屬性

先前的範例會示範如何使用 「 OnValueChanged() 」 傳播到另一個網域屬性值。每個屬性都有它自己的儲存的值。

相反地,您可以考慮為計算的屬性定義衍生的屬性。情況下,屬性有它自己,沒有儲存,就要定義其值,必要時,被評估函式。如需詳細資訊,請參閱 計算及自訂的儲存區屬性

代替先前的範例中,您可以設定 欄位的 TextLengthCount 是計算 DSL 定義中。會提供您自己取得這個定義域屬性的方法。取得 方法會傳回的目前長度 文字的字串。

不過,計算內容的潛在的缺點是會評估運算式,每次使用值,這可能會出現效能問題。此外,就不會有 OnValueChanging() 和 OnValueChanged() 上計算的屬性。

Bb126481.collapse_all(zh-tw,VS.110).gif另一個技術: 變更規則

如果您定義的 ChangeRule,它會執行最後的交易,在其中變更屬性的值。如需詳細資訊,請參閱規則傳播模型內的變更

如果在一個交易中做了多項變更,當它們都已全部完成,也會執行 ChangeRule。反之,OnValue...某些變更尚未執行時,會執行方法。取決於您想要達成,這可能會讓 ChangeRule 較為適合。

您也可以使用 ChangeRule 來調整屬性的新值,才能將它保存在特定範圍內。

注意事項警告

如果規則會對存放區內容中做了變更,其他的規則和屬性處理常式可能會觸發。如果規則變更時觸發它的屬性,將會再次呼叫它。您必須確定規則定義不會造成無止盡的觸發。

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) }; 
 }
} 

範例

Bb126481.collapse_all(zh-tw,VS.110).gif描述

下列範例會覆寫網域屬性的屬性處理常式,並通知使用者時的屬性, ExampleElement網域類別已變更。

Bb126481.collapse_all(zh-tw,VS.110).gif程式碼

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);
      }
    }
  }
}

請參閱

參考

OnValueChanged

OnValueChanging