Programy obsługi zdarzeń propagujące zmiany poza modelem
W zestawie SDK wizualizacji i modelowania można zdefiniować programy obsługi zdarzeń magazynu w celu propagowania zmian do zasobów spoza magazynu, takich jak zmienne inne niż przechowywanie, pliki, modele w innych magazynach lub inne rozszerzenia programu Visual Studio. Programy obsługi zdarzeń magazynu są wykonywane po zakończeniu transakcji, w której wystąpiło zdarzenie wyzwalające. Są one również wykonywane w operacji Cofnij lub Wykonaj ponownie. W związku z tym, w przeciwieństwie do reguł przechowywania, zdarzenia magazynu są najbardziej przydatne do aktualizowania wartości spoza magazynu. W przeciwieństwie do zdarzeń platformy .NET programy obsługi zdarzeń magazynu są rejestrowane w celu nasłuchiwania klasy: nie trzeba rejestrować oddzielnej procedury obsługi dla każdego wystąpienia. Aby uzyskać więcej informacji na temat wybierania między różnymi sposobami obsługi zmian, zobacz Reagowanie na zmiany i Propagacja zmian.
Graficzna powierzchnia i inne kontrolki interfejsu użytkownika to przykłady zasobów zewnętrznych, które mogą być obsługiwane przez zdarzenia magazynu.
Aby zdefiniować zdarzenie magazynu
Wybierz typ zdarzenia, które chcesz monitorować. Aby zapoznać się z pełną listą, zapoznaj się z właściwościami .EventManagerDirectory Każda właściwość odpowiada typowi zdarzenia. Najczęściej używane typy zdarzeń to:
ElementAdded
— wyzwalane po utworzeniu elementu modelu, łącza relacji, kształtu lub łącznika.ElementPropertyChanged — wyzwalany po zmianie wartości
Normal
właściwości domeny. Zdarzenie jest wyzwalane tylko wtedy, gdy nowe i stare wartości nie są równe. Nie można zastosować zdarzenia do właściwości obliczeniowych i niestandardowych magazynu.Nie można go zastosować do właściwości roli odpowiadających linkom relacji. Zamiast tego użyj polecenia
ElementAdded
, aby monitorować relację domeny.ElementDeleted
— wyzwalane po usunięciu elementu modelu, relacji, kształtu lub łącznika. Nadal można uzyskać dostęp do wartości właściwości elementu, ale nie będzie mieć relacji z innymi elementami.
Dodaj definicję klasy częściowej dla pliku YourDslDocData w osobnym pliku kodu w projekcie DslPackage .
Napisz kod zdarzenia jako metodę, jak w poniższym przykładzie. Może to być
static
wartość , chyba że chcesz uzyskać dostęp doDocData
elementu .Zastąpić
OnDocumentLoaded()
, aby zarejestrować procedurę obsługi. Jeśli masz więcej niż jedną procedurę obsługi, możesz zarejestrować je wszystkie w tym samym miejscu.
Lokalizacja kodu rejestracji nie jest krytyczna. DocView.LoadView()
jest lokalizacją alternatywną.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Modeling;
namespace Company.MusicLib
{
partial class MusicLibDocData
{
// Register store events here or in DocView.LoadView().
protected override void OnDocumentLoaded()
{
base.OnDocumentLoaded(); // Don't forget this.
#region Store event handler registration.
Store store = this.Store;
EventManagerDirectory emd = store.EventManagerDirectory;
DomainRelationshipInfo linkInfo = store.DomainDataDirectory
.FindDomainRelationship(typeof(ArtistAppearsInAlbum));
emd.ElementAdded.Add(linkInfo,
new EventHandler<ElementAddedEventArgs>(AddLink));
emd.ElementDeleted.Add(linkInfo,
new EventHandler<ElementDeletedEventArgs>(RemoveLink));
#endregion Store event handlers.
}
private void AddLink(object sender, ElementAddedEventArgs e)
{
ArtistAppearsInAlbum link = e.ModelElement as ArtistAppearsInAlbum;
if (link != null)
ExternalDatabase.Add(link.Artist.Name, link.Album.Title);
}
private void RemoveLink(object sender, ElementDeletedEventArgs e)
{
ArtistAppearsInAlbum link = e.ModelElement as ArtistAppearsInAlbum;
if (link != null)
ExternalDatabase.Delete(link.Artist.Name, link.Album.Title);
}
}
}
Używanie zdarzeń do dokonywania niemożliwych korekt w magazynie
Zdarzenia magazynu nie są zwykle używane do propagowania zmian w magazynie, ponieważ program obsługi zdarzeń jest wykonywany po zatwierdzeniu transakcji. Zamiast tego należy użyć reguły magazynu. Aby uzyskać więcej informacji, zobacz Reguły propagacji zmian w modelu.
Można jednak użyć programu obsługi zdarzeń, aby wprowadzić dodatkowe aktualizacje do magazynu, jeśli chcesz, aby użytkownik mógł cofnąć dodatkowe aktualizacje oddzielnie od oryginalnego zdarzenia. Załóżmy na przykład, że małe litery są zwykle konwencją tytułów albumów. Można napisać procedurę obsługi zdarzeń magazynu, która poprawia tytuł do małych liter po wpisaniu go przez użytkownika w wielkim przypadku. Jednak użytkownik może użyć polecenia Cofnij, aby anulować korektę, przywracając wielkie litery. Drugie Cofnij spowoduje usunięcie zmiany użytkownika.
Natomiast jeśli napisałeś regułę sklepu, aby wykonać to samo, zmiana użytkownika i korekta będzie w tej samej transakcji, aby użytkownik nie mógł cofnąć korekty bez utraty oryginalnej zmiany.
partial class MusicLibDocView
{
// Register store events here or in DocData.OnDocumentLoaded().
protected override void LoadView()
{
/* Register store event handler for Album Title property. */
// Get reflection data for property:
DomainPropertyInfo propertyInfo =
this.DocData.Store.DomainDataDirectory
.FindDomainProperty(Album.TitleDomainPropertyId);
// Add to property handler list:
this.DocData.Store.EventManagerDirectory
.ElementPropertyChanged.Add(propertyInfo,
new EventHandler<ElementPropertyChangedEventArgs>
(AlbumTitleAdjuster));
/*
// Alternatively, you can set one handler for
// all properties of a class.
// Your handler has to determine which property changed.
DomainClassInfo classInfo = this.Store.DomainDataDirectory
.FindDomainClass(typeof(Album));
this.Store.EventManagerDirectory
.ElementPropertyChanged.Add(classInfo,
new EventHandler<ElementPropertyChangedEventArgs>
(AlbumTitleAdjuster));
*/
return base.LoadView();
}
// Undoable adjustment after a property is changed.
// Method can be static since no local access.
private static void AlbumTitleAdjuster(object sender,
ElementPropertyChangedEventArgs e)
{
Album album = e.ModelElement as Album;
Store store = album.Store;
// We mustn't update the store in an Undo:
if (store.InUndoRedoOrRollback
|| store.InSerializationTransaction)
return;
if (e.DomainProperty.Id == Album.TitleDomainPropertyId)
{
string newValue = (string)e.NewValue;
string lowerCase = newValue.ToLowerInvariant();
if (!newValue.Equals(lowerCase))
{
using (Transaction t = store.TransactionManager
.BeginTransaction("adjust album title"))
{
album.Title = lowerCase;
t.Commit();
} // Beware! This could trigger the event again.
}
}
// else other properties of this class.
}
Jeśli napiszesz zdarzenie, które aktualizuje magazyn:
Użyj polecenia
store.InUndoRedoOrRollback
, aby uniknąć wprowadzania zmian w elementach modelu w funkcji Cofnij. Menedżer transakcji ustawi wszystko w magazynie z powrotem na jego oryginalny stan.Użyj polecenia
store.InSerializationTransaction
, aby uniknąć wprowadzania zmian podczas ładowania modelu z pliku.Zmiany spowodują wyzwolenie dalszych zdarzeń. Upewnij się, że unikasz nieskończonej pętli.
Przechowywanie typów zdarzeń
Każdy typ zdarzenia odpowiada kolekcji w store.EventManagerDirectory. Programy obsługi zdarzeń można dodawać lub usuwać w dowolnym momencie, ale zwykle należy je dodawać po załadowaniu dokumentu.
EventManagerDirectory Nazwa właściwości |
Wykonywane, gdy |
---|---|
ElementAdded | Tworzone jest wystąpienie klasy domeny, relacji domeny, kształtu, łącznika lub diagramu. |
ElementDeleted | Element modelu został usunięty z katalogu elementów magazynu i nie jest już źródłem ani obiektem docelowym żadnej relacji. Element nie jest w rzeczywistości usuwany z pamięci, ale jest zachowywany w przypadku przyszłego cofania. |
ElementEventsBegun | Wywoływane na końcu transakcji zewnętrznej. |
ElementEventsEnded | Wywoływane po przetworzeniu wszystkich innych zdarzeń. |
ElementMoved | Element modelu został przeniesiony z jednej partycji magazynu do innej. Nie jest to związane z lokalizacją kształtu na diagramie. |
ElementPropertyChanged | Wartość właściwości domeny została zmieniona. Jest to wykonywane tylko wtedy, gdy stare i nowe wartości są nierówne. |
RolePlayerChanged | Jedna z dwóch ról (kończy) relacji odwołuje się do nowego elementu. |
RolePlayerOrderChanged | W roli o wielodostępności większej niż 1 sekwencja łączy uległa zmianie. |
TransactionBeginning | |
TransactionCommitted | |
TransactionRolledBack |
Powiązana zawartość
Uwaga
Składnik Przekształcanie szablonu tekstu jest automatycznie instalowany w ramach obciążenia programistycznego rozszerzenia programu Visual Studio. Można go również zainstalować na karcie Poszczególne składniki Instalator programu Visual Studio w kategorii Zestawy SDK, biblioteki i struktury. Zainstaluj składnik Zestawu SDK modelowania na karcie Poszczególne składniki.