Obslužné rutiny změny hodnoty vlastnosti domény
Pokud se v jazyce specifickém pro doménu sady Visual Studio změní hodnota vlastnosti domény, OnValueChanging()
vyvolá se v obslužné rutině vlastnosti domény metody a OnValueChanged()
metody. Pokud chcete na změnu reagovat, můžete tyto metody přepsat.
Přepsání metod obslužné rutiny vlastností
Každá vlastnost domény jazyka specifického pro vaši doménu se zpracovává třídou, která je vnořená do nadřazené třídy domény. Jeho název se řídí formátem PropertyNamePropertyHandler. Tuto třídu obslužné rutiny vlastnosti můžete zkontrolovat v souboru Dsl\Generated Code\DomainClasses.cs. Ve třídě je OnValueChanging()
volána bezprostředně před změnou hodnoty a OnValueChanged()
je volána okamžitě po změně hodnoty.
Předpokládejme například, že máte třídu domény s názvem Comment
string domain vlastnost pojmenovanou Text
a celočíselnou vlastnost s názvem TextLengthCount
. Pokud chcete, TextLengthCount
aby vždy obsahoval délku Text
řetězce, můžete do samostatného souboru v projektu Dsl napsat následující kód:
// 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;
}
}
}
Všimněte si následujících bodů o obslužných rutinách vlastností:
Metody obslužné rutiny vlastnosti jsou volány jak když uživatel provede změny vlastnosti domény, a když kód programu přiřadí k vlastnosti jinou hodnotu.
Metody se volají pouze v případech, kdy se hodnota skutečně změní. Obslužná rutina není vyvolána, pokud kód programu přiřadí hodnotu, která se rovná aktuální hodnotě.
Počítané a vlastní vlastnosti domény úložiště nemají metody OnValueChanged a OnValueChanging.
K úpravě nové hodnoty nelze použít obslužnou rutinu změny. Pokud to chcete udělat, například omezit hodnotu na konkrétní rozsah, definujte hodnotu
ChangeRule
.Obslužnou rutinu změny nelze přidat do vlastnosti, která představuje roli relace. Místo toho definujte třídu
AddRule
relace a na nějDeleteRule
. Tato pravidla se aktivují při vytváření nebo změně odkazů. Další informace naleznete v tématu Pravidla šíření změn v rámci modelu.
Změny v úložišti a mimo obchod
Metody obslužné rutiny vlastnosti jsou volána uvnitř transakce, která iniciovala změnu. Proto můžete v úložišti provádět další změny bez otevření nové transakce. Vaše změny můžou vést k dalším voláním obslužné rutiny.
Při vrácení transakce zpět, opětovné provedení nebo vrácení zpět byste neměli provádět změny v úložišti, tj. změny prvků modelu, relací, obrazců, diagramů spojnic nebo jejich vlastností.
Kromě toho byste obvykle neaktualizují hodnoty při načítání modelu ze souboru.
Změny modelu by proto měly být chráněny testem takto:
if (!store.InUndoRedoOrRollback && !store. InSerializationTransaction)
{
this.TextLength = ...; // in-store changes
}
Pokud obslužná rutina vlastnosti naopak šíří změny mimo úložiště, například do souboru, databáze nebo neukládajících proměnných, měli byste tyto změny provést vždy, aby se externí hodnoty aktualizovaly, když uživatel vyvolá zpět nebo znovu.
Zrušení změny
Pokud chcete zabránit změně, můžete vrátit zpět aktuální transakci. Můžete například chtít zajistit, aby vlastnost zůstala v určitém rozsahu.
if (newValue > 10)
{
store.TransactionManager.CurrentTransaction.Rollback();
System.Windows.Forms.MessageBox.Show("Value must be less than 10");
}
Alternativní technika: Počítané vlastnosti
Předchozí příklad ukazuje, jak lze OnValueChanged() použít k šíření hodnot z jedné vlastnosti domény do jiné. Každá vlastnost má svou vlastní uloženou hodnotu.
Místo toho byste mohli zvážit definování odvozené vlastnosti jako počítané vlastnosti. V takovém případě vlastnost nemá žádné vlastní úložiště a je definována funkce je vyhodnocena vždy, když je požadována jeho hodnota. Další informace naleznete v tématu Počítané a vlastní vlastnosti úložiště.
Místo předchozího příkladu byste mohli nastavit pole TextLengthCount
Kind pro výpočet v definici DSL. Pro tuto vlastnost domény byste zadali vlastní metodu Get . Metoda Get by vrátila aktuální délku Text
řetězce.
Potenciální nevýhodou počítaných vlastností je ale to, že se výraz vyhodnocuje při každém použití hodnoty, což může představovat problém s výkonem. Také neexistuje žádný OnValueChanging() a OnValueChanged() pro počítanou vlastnost.
Alternativní technika: Změna pravidel
Pokud definujete ChangeRule, provede se na konci transakce, ve které se hodnota vlastnosti změní. Další informace naleznete v tématu Pravidla šíření změn v rámci modelu.
Pokud se v jedné transakci provede několik změn, provede se příkaz ChangeRule po dokončení. Naproti tomu OnValue... metody jsou provedeny, pokud nebyly provedeny některé změny. V závislosti na tom, co chcete dosáhnout, může být vhodnější změnit pravidla.
Pomocí příkazu ChangeRule můžete také upravit novou hodnotu vlastnosti, aby byla v určitém rozsahu.
Upozorňující
Pokud pravidlo provede změny obsahu úložiště, můžou se aktivovat další pravidla a obslužné rutiny vlastností. Pokud pravidlo změní vlastnost, která ji aktivovala, bude znovu volána. Musíte se ujistit, že definice pravidel nemají za následek nekonečné spouštění.
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) };
}
}
Příklad
Popis
Následující příklad přepíše obslužnou rutinu vlastnosti domény a upozorní uživatele, když se vlastnost pro ExampleElement
třídu domény změnila.
Kód
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);
}
}
}
}