Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Pokud se v jazyce specifickém pro doménu sady Visual Studio změní hodnota vlastnosti domény, metody OnValueChanging() a OnValueChanged() jsou vyvolány v obslužné rutině této vlastnosti. Pokud chcete na změnu reagovat, můžete tyto metody přepsat.
Přepište metody 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. Třídu obsluhující vlastnost 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 doménovou třídu nazvanou Comment s řetězcovou doménovou 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 zpracovatelích vlastností:
Metody pro obsluhu vlastností jsou volány jakmile uživatel provede změny na vlastnosti domény, nebo když programový kód přiřadí 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.Nelze přidat zpracovatel změny k vlastnosti, která představuje roli vztahu. Místo toho definujte
AddRuleaDeleteRuleve třídě relace. 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 obchodě a mimo něj
Metody správce vlastností jsou volány uvnitř transakce, která iniciovala změnu. Proto můžete v obchodě provádět více změn bez otevření nové transakce. Vaše změny můžou vést k dalším voláním handleru.
Při rušení, opětovném provádění nebo vrácení transakce 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 neaktualizovali 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 váš obslužný modul pro vlastnosti naopak šíří změny mimo úložiště, například do souboru, databáze nebo jiných externích proměnných, měli byste tyto změny provádět vždy, aby se externí hodnoty aktualizovaly, když uživatel vyvolá příkaz zpět nebo opakovat.
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 tomto případě nemá vlastnost žádné vlastní úložiště a její definující funkce je vyhodnocena vždy, když je požadována její 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 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á funkce 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, pravidlo ChangeRule se vykoná, když jsou všechny dokončeny. Naproti tomu metody OnValue... jsou vykonány, když některé změny nebyly provedeny. 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.
Výstraha
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) };
}
}
Example
Description
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.
Code
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);
}
}
}
}