Dostosowywanie okno Właściwości
Wygląd i zachowanie okna właściwości można dostosować w języku specyficznym dla domeny (DSL) w programie Visual Studio. W definicji DSL definiujesz właściwości domeny w każdej klasie domeny. Domyślnie po wybraniu wystąpienia klasy na diagramie lub w Eksploratorze modeli każda właściwość domeny jest wyświetlana w oknie właściwości. Dzięki temu można wyświetlać i edytować wartości właściwości domeny, nawet jeśli nie zostały one zamapowane na pola kształtu na diagramie.
Nazwy, opisy i kategorie
Nazwa i nazwa wyświetlana. W definicji właściwości domeny nazwa wyświetlana właściwości jest nazwą wyświetlaną w czasie wykonywania w oknie właściwości. Z kolei nazwa jest używana podczas pisania kodu programu w celu zaktualizowania właściwości. Nazwa musi być poprawną nazwą alfanumeryczną CLR, ale nazwa wyświetlana może zawierać spacje.
Po ustawieniu nazwy właściwości w definicji DSL jej nazwa wyświetlana jest automatycznie ustawiana na kopię nazwy. Jeśli napiszesz nazwę z literą Pascal, taką jak "FuelGauge", nazwa wyświetlana będzie automatycznie zawierać spację: "Miernik paliwa". Można jednak jawnie ustawić nazwę wyświetlaną na inną wartość.
Opis. Opis właściwości domeny jest wyświetlany w dwóch miejscach:
W dolnej części okna właściwości, gdy użytkownik wybierze właściwość. Można go użyć, aby wyjaśnić użytkownikowi, co reprezentuje właściwość.
W wygenerowany kod programu. Jeśli używasz dokumentacji do wyodrębniania dokumentacji interfejsu API, będzie ona wyświetlana jako opis tej właściwości w interfejsie API.
Kategoria. Kategoria to nagłówek w okno Właściwości.
Uwidaczniaj funkcje stylu
Niektóre funkcje dynamiczne elementów graficznych mogą być reprezentowane lub uwidocznione jako właściwości domeny. Funkcja, która została udostępniona w ten sposób, może zostać zaktualizowana przez użytkownika i można ją łatwiej zaktualizować za pomocą kodu programu.
Kliknij prawym przyciskiem myszy klasę kształtu w definicji DSL, wskaż polecenie Dodaj uwidocznione, a następnie wybierz funkcję.
Na kształtach można uwidocznić właściwości FillColor, OutlineColor, TextColor, OutlineDashStyle, OutlineThickness i FillGradientMode . W łącznikach można uwidocznić właściwości Color,
TextColor, DashStyle i Thickness. Na diagramach można uwidocznić właściwości FillColor i TextColor.
Przekazywanie: Wyświetlanie właściwości powiązanych elementów
Gdy użytkownik dsL wybierze element w modelu, właściwości tego elementu są wyświetlane w oknie właściwości. Można jednak również wyświetlić właściwości określonych powiązanych elementów. Jest to przydatne, jeśli zdefiniowano grupę elementów, które współpracują ze sobą. Można na przykład zdefiniować element główny i opcjonalny element wtyczki. Jeśli główny element jest mapowany na kształt, a drugi nie, warto zobaczyć wszystkie ich właściwości tak, jakby znajdowały się w jednym elemenie.
Ten efekt nazywa się przekazywaniem właściwości i odbywa się to automatycznie w kilku przypadkach. W innych przypadkach można osiągnąć przekazywanie właściwości przez zdefiniowanie deskryptora typu domeny.
Domyślne przypadki przekazywania właściwości
Gdy użytkownik wybierze kształt lub łącznik lub element w Eksploratorze, w okno Właściwości zostaną wyświetlone następujące właściwości:
Właściwości domeny zdefiniowane w klasie domeny elementu modelu, w tym właściwości zdefiniowane w klasach bazowych. Wyjątkiem są właściwości domeny, dla których ustawiono opcję Przeglądanie ma wartość
False
.Nazwy elementów połączonych za pośrednictwem relacji, które mają wiele wartości 0..1. Zapewnia to wygodną metodę wyświetlania opcjonalnych elementów połączonych, nawet jeśli nie zdefiniowano mapowania łącznika dla relacji.
Właściwości domeny relacji osadzania, która jest przeznaczona dla elementu . Ponieważ osadzanie relacji zwykle nie jest wyświetlane jawnie, pozwala to użytkownikowi zobaczyć ich właściwości.
Właściwości domeny zdefiniowane na wybranym kształcie lub łączniku.
Dodawanie przekazywania właściwości
Aby przekazać właściwość, należy zdefiniować deskryptor typu domeny. Jeśli masz relację domeny między dwiema klasami domen, możesz użyć deskryptora typu domeny, aby ustawić właściwość domeny w pierwszej klasie na wartość właściwości domeny w drugiej klasie domeny. Jeśli na przykład masz relację między klasą domeny Book i klasą domeny Author, możesz użyć deskryptora typu domeny, aby właściwość Name autora książki pojawiła się w okno Właściwości, gdy użytkownik wybierze książkę.
Uwaga
Przekazywanie właściwości wpływa tylko na okno Właściwości podczas edytowania modelu przez użytkownika. Nie definiuje właściwości domeny w klasie odbierania. Jeśli chcesz uzyskać dostęp do właściwości domeny przekazanej w innych częściach definicji DSL lub w kodzie programu, musisz uzyskać dostęp do elementu przekazywania.
W poniższej procedurze przyjęto założenie, że utworzono rozszerzenie DSL. Pierwsze kilka kroków zawiera podsumowanie wymagań wstępnych.
Przekazywanie właściwości z innego elementu
Utwórz rozwiązanie narzędzi językowych specyficznych dla domeny, które zawiera co najmniej dwie klasy, które w tym przykładzie są nazywane książką i autorem. Powinna istnieć relacja jednego rodzaju między książką a autorem.
Wielokrotność roli źródłowej (rola po stronie książki ) powinna mieć wartość 0..1 lub 1..1, tak aby każda książka ma jedną autora.
W Eksploratorze DSL kliknij prawym przyciskiem myszy klasę domeny Book, a następnie kliknij polecenie Add New DomainTypeDescriptor (Dodaj nową klasę DomainTypeDescriptor).
Węzeł o nazwie Ścieżki deskryptorów właściwości niestandardowych jest wyświetlany w węźle Deskryptora niestandardowego typu.
Kliknij prawym przyciskiem myszy węzeł Deskryptora niestandardowego typu, a następnie kliknij polecenie Dodaj nową ścieżkę właściwości.
Nowa ścieżka właściwości jest wyświetlana w węźle Ścieżki deskryptorów właściwości niestandardowych.
Wybierz nową ścieżkę właściwości, a w oknie Właściwości ustaw wartość Ścieżka na właściwość na ścieżkę odpowiedniego elementu modelu.
Ścieżkę można edytować w widoku drzewa, klikając strzałkę w dół po prawej stronie tej właściwości. Aby uzyskać więcej informacji na temat ścieżek domeny, zobacz Składnia ścieżki domeny. Po jego edycji ścieżka powinna przypominać bookReferencesAuthor.Author/! Autor.
Ustaw właściwość na właściwość Nazwa domeny Author.
Ustaw wartość Nazwa wyświetlana na Nazwa autora.
Przekształć wszystkie szablony, skompiluj i uruchom rozszerzenie DSL.
Na diagramie modelu utwórz książkę, autora i połącz je przy użyciu relacji referencyjnej. Wybierz element książki, a w okno Właściwości obok właściwości książki powinna zostać wyświetlona nazwa autora. Zmień nazwę połączonego autora lub połącz książkę z innym autorem i zwróć uwagę, że zmienia się nazwa autora książki.
Edytory właściwości niestandardowych
Okno właściwości zapewnia odpowiednie domyślne środowisko edycji dla typu każdej właściwości domeny. Na przykład w przypadku typu wyliczonego użytkownik widzi listę rozwijaną, a w przypadku właściwości liczbowej użytkownik może wprowadzić cyfry. Dotyczy to tylko typów wbudowanych. Jeśli określisz typ zewnętrzny, użytkownik będzie mógł zobaczyć wartości właściwości, ale nie będzie go edytować.
Można jednak określić następujące edytory i typy:
Inny edytor, który jest używany z typem standardowym. Można na przykład określić edytor ścieżek pliku dla właściwości ciągu.
Typ zewnętrzny właściwości domeny i edytor.
Edytor .NET, taki jak edytor ścieżek plików, lub możesz utworzyć własny niestandardowy edytor właściwości.
Konwersja między typem zewnętrznym a typem, takim jak Ciąg, który ma edytor domyślny.
W języku DSL typ zewnętrzny to dowolny typ, który nie jest jednym z prostych typów (takich jak wartość logiczna lub int32) lub ciąg.
Definiowanie właściwości domeny, która ma typ zewnętrzny
W Eksplorator rozwiązań dodaj odwołanie do zestawu (DLL), który zawiera typ zewnętrzny w projekcie Dsl.
Zestaw może być zestawem .NET lub zestawem dostarczonym przez Ciebie.
Dodaj typ do listy Typy domen, chyba że zostało to już zrobione.
Otwórz plik DslDefinition.dsl i w Eksploratorze DSL kliknij prawym przyciskiem myszy węzeł główny, a następnie kliknij polecenie Dodaj nowy typ zewnętrzny.
Nowy wpis zostanie wyświetlony w węźle Typy domen.
Ostrzeżenie
Element menu znajduje się w węźle głównym DSL, a nie w węźle Typy domen.
Ustaw nazwę i przestrzeń nazw nowego typu w okno Właściwości.
Dodaj właściwość domeny do klasy domeny w zwykły sposób.
W okno Właściwości wybierz typ zewnętrzny z listy rozwijanej w polu Typ.
Na tym etapie użytkownicy mogą wyświetlać wartości właściwości, ale nie mogą go edytować. Wyświetlane wartości są uzyskiwane z
ToString()
funkcji . Możesz napisać kod programu, który ustawia wartość właściwości, na przykład w poleceniu lub regule.
Ustawianie edytora właściwości
Dodaj atrybut CLR do właściwości domeny w następującym formularzu:
[System.ComponentModel.Editor (
typeof(AnEditor),
typeof(System.Drawing.Design.UITypeEditor))]
Atrybut właściwości można ustawić przy użyciu wpisu Atrybut niestandardowy w okno Właściwości.
Typ AnEditor
musi pochodzić z typu określonego w drugim parametrze. Drugi parametr powinien mieć wartość UITypeEditor lub ComponentEditor. Aby uzyskać więcej informacji, zobacz EditorAttribute.
Możesz określić własny edytor lub edytor .NET, taki jak FileNameEditor lub ImageEditor. Na przykład użyj poniższej procedury, aby mieć właściwość, w której użytkownik może wprowadzić nazwę pliku.
Definiowanie właściwości domeny nazwy pliku
Dodaj właściwość domeny do klasy domeny w definicji DSL.
Wybierz nową właściwość. W polu Atrybut niestandardowy w okno Właściwości wprowadź następujący atrybut. Aby wprowadzić ten atrybut, kliknij wielokropek [...] a następnie wprowadź nazwę atrybutu i parametry oddzielnie:
[System.ComponentModel.Editor ( typeof(System.Windows.Forms.Design.FileNameEditor) , typeof(System.Drawing.Design.UITypeEditor))]
Pozostaw wartość Typ właściwości domeny w domyślnym ustawieniu ciągu.
Aby przetestować edytor, sprawdź, czy użytkownicy mogą otworzyć edytor nazw plików, aby edytować właściwość domeny.
Naciśnij klawisze CTRL+F5 lub F5. W rozwiązaniu do debugowania otwórz plik testowy. Utwórz element klasy domeny i wybierz go.
W okno Właściwości wybierz właściwość domeny. Pole wartości zawiera wielokropek [...].
Kliknij wielokropek. Zostanie wyświetlone okno dialogowe pliku. Wybierz plik i zamknij okno dialogowe. Ścieżka pliku jest teraz wartością właściwości domeny.
Definiowanie własnego edytora właściwości
Możesz zdefiniować własny edytor. Można to zrobić, aby umożliwić użytkownikowi edytowanie zdefiniowanego typu lub edytowanie standardowego typu w specjalny sposób. Można na przykład zezwolić użytkownikowi na wprowadzanie ciągu reprezentującego formułę.
Edytor definiuje się, pisząc klasę pochodzącą z UITypeEditorklasy . Klasa musi przesłonić:
EditValue, aby wchodzić w interakcje z użytkownikiem i aktualizować wartość właściwości.
GetEditStyle, aby określić, czy edytor otworzy okno dialogowe, czy udostępni menu rozwijane.
Można również podać graficzną reprezentację wartości właściwości, która będzie wyświetlana w siatce właściwości. W tym celu przesłoń GetPaintValueSupported
wartości i PaintValue
. Aby uzyskać więcej informacji, zobacz UITypeEditor.
Uwaga
Dodaj kod w osobnym pliku kodu w projekcie Dsl .
Na przykład:
internal class TextFileNameEditor : System.Windows.Forms.Design.FileNameEditor
{
protected override void InitializeDialog(System.Windows.Forms.OpenFileDialog openFileDialog)
{
base.InitializeDialog(openFileDialog);
openFileDialog.Filter = "Text files(*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog.Title = "Select a text file";
}
}
Aby użyć tego edytora, ustaw atrybut niestandardowy właściwości domeny na:
[System.ComponentModel.Editor (
typeof(MyNamespace.TextFileNameEditor)
, typeof(System.Drawing.Design.UITypeEditor))]
Aby uzyskać więcej informacji, zobacz UITypeEditor.
Podaj listę rozwijaną wartości
Możesz podać listę wartości do wyboru przez użytkownika.
Uwaga
Ta technika zawiera listę wartości, które mogą ulec zmianie w czasie wykonywania. Jeśli chcesz podać listę, która nie zmienia się, rozważ użycie wyliczonego typu jako typu właściwości domeny.
Aby zdefiniować listę wartości standardowych, należy dodać do właściwości domeny atrybut CLR, który ma następujący formularz:
[System.ComponentModel.TypeConverter
(typeof(MyTypeConverter))]
Zdefiniuj klasę pochodzącą z klasy TypeConverter. Dodaj kod w osobnym pliku w projekcie Dsl . Na przykład:
/// <summary>
/// Type converter that provides a list of values
/// to be displayed in the property grid.
/// </summary>
/// <remarks>This type converter returns a list
/// of the names of all "ExampleElements" in the
/// current store.</remarks>
public class MyTypeConverter : System.ComponentModel.TypeConverter
{
/// <summary>
/// Return true to indicate that we return a list of values to choose from
/// </summary>
/// <param name="context"></param>
public override bool GetStandardValuesSupported
(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
}
/// <summary>
/// Returns true to indicate that the user has
/// to select a value from the list
/// </summary>
/// <param name="context"></param>
/// <returns>If we returned false, the user would
/// be able to either select a value from
/// the list or type in a value that is not in the list.</returns>
public override bool GetStandardValuesExclusive
(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
}
/// <summary>
/// Return a list of the values to display in the grid
/// </summary>
/// <param name="context"></param>
/// <returns>A list of values the user can choose from</returns>
public override StandardValuesCollection GetStandardValues
(System.ComponentModel.ITypeDescriptorContext context)
{
// Try to get a store from the current context
// "context.Instance" returns the element(s) that
// are currently selected i.e. whose values are being
// shown in the property grid.
// Note that the user could have selected multiple objects,
// in which case context.Instance will be an array.
Store store = GetStore(context.Instance);
List<string> values = new List<string>();
if (store != null)
{
values.AddRange(store.ElementDirectory
.FindElements<ExampleElement>()
.Select<ExampleElement, string>(e =>
{
return e.Name;
}));
}
return new StandardValuesCollection(values);
}
/// <summary>
/// Attempts to get to a store from the currently selected object(s)
/// in the property grid.
/// </summary>
private Store GetStore(object gridSelection)
{
// We assume that "instance" will either be a single model element, or
// an array of model elements (if multiple items are selected).
ModelElement currentElement = null;
object[] objects = gridSelection as object[];
if (objects != null && objects.Length > 0)
{
currentElement = objects[0] as ModelElement;
}
else
{
currentElement = gridSelection as ModelElement;
}
return (currentElement == null) ? null : currentElement.Store;
}
}