Eigenschaftsraster
Eigenschaften nach Kategorien wie im Eigenschaftenfenster von Visual Studio: die einer Schaltfläche (direkt aus ihren registrierten Eigenschaften, ohne Reflexion) oder einer Tabellenspalte wie im Tabellen-Designer von SSMS. Enter übernimmt, Esc verwirft, ein ungültiger Wert wird rot gemeldet; oben Kategorien, alphabetisch und Suche, unten die Beschreibung.


KXAML
EigenschaftsrasterSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
xmlns:x="https://ui.kuonen.org/kxaml/x"
x:Class="Kuonen.UI.Galerie.Seiten.EigenschaftsrasterVorfuehrung"
Orientation="Horizontal" Spacing="16">
<StackPanel Spacing="8">
<ComboBox x:Name="Objekt" MinWidth="160" />
<PropertyGrid x:Name="Raster" Width="360" Height="420" />
<TextBlock x:Name="Status" Text="Noch nichts geändert." />
</StackPanel>
<Border Padding="24" VerticalAlignment="Top">
<Button x:Name="Vorschau" Content="Vorschau" />
</Border>
</StackPanel>EigenschaftsrasterSeite.kxaml.cs
using Kuonen.UI;
namespace Kuonen.UI.Galerie.Seiten;
public sealed partial class EigenschaftsrasterSeite
{
protected override Func<UIElement>? KxamlFabrik => () => new EigenschaftsrasterVorfuehrung();
}
/// <summary>KXAML-Fassung der Seite Eigenschaftsraster: der Aufbau steht in EigenschaftsrasterSeite.kxaml, hier das Verhalten.</summary>
public sealed partial class EigenschaftsrasterVorfuehrung
{
public EigenschaftsrasterVorfuehrung()
{
InitializeComponent();
EigenschaftsrasterSeite.Verdrahte(Raster, Objekt, Vorschau, Status);
}
}C#
EigenschaftsrasterSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Layout;
namespace Kuonen.UI.Galerie.Seiten;
/// <summary>Galerie-Seite: das Eigenschaftsraster (<see cref="PropertyGrid"/>) mit einer Schaltfläche und einer Tabellenspalte.</summary>
public sealed partial class EigenschaftsrasterSeite : GalerieSeite
{
public override string Titel => "Eigenschaftsraster";
public override string Beschreibung =>
"Eigenschaften nach Kategorien wie im Eigenschaftenfenster von Visual Studio: die einer Schaltfläche (direkt aus ihren registrierten "
+ "Eigenschaften, ohne Reflexion) oder einer Tabellenspalte wie im Tabellen-Designer von SSMS. Enter übernimmt, Esc verwirft, ein ungültiger "
+ "Wert wird rot gemeldet; oben Kategorien, alphabetisch und Suche, unten die Beschreibung.";
public override string Stichworte => "PropertyGrid Eigenschaften Eigenschaftenfenster Inspektor Editor Kategorien Tabellen-Designer Spalte";
public override string Datei => nameof(EigenschaftsrasterSeite);
internal static readonly string[] Objekte = ["Schaltfläche", "Tabellenspalte"];
/// <summary>Eine Spalte im Tabellen-Designer: beschreibt ihre Eigenschaften selbst.</summary>
public sealed class Tabellenspalte : IPropertyGridSource
{
public string Name { get; set; } = "KundeId";
public string Datentyp { get; set; } = "int";
public int Laenge { get; set; } = 4;
public bool NullZulassen { get; set; }
public string? Standardwert { get; set; }
public bool Identitaet { get; set; } = true;
public IReadOnlyList<PropertyGridProperty> GetProperties() =>
[
new("Name", typeof(string), () => Name, v => Name = (string)v!) { Category = "Spalte", Description = "Der Name der Spalte." },
new("Datentyp", typeof(string), () => Datentyp, v => Datentyp = (string)v!)
{
Category = "Spalte", Description = "Der SQL-Datentyp.", Options = ["int", "bigint", "decimal", "nvarchar", "datetime2", "bit"],
},
new("Laenge", typeof(int), () => Laenge, v => Laenge = (int)v!) { DisplayName = "Länge", Category = "Spalte", Description = "Länge in Bytes oder Zeichen." },
new("NullZulassen", typeof(bool), () => NullZulassen, v => NullZulassen = (bool)v!)
{
DisplayName = "NULL zulassen", Category = "Spalte", Description = "Die Spalte darf leer bleiben.",
},
new("Standardwert", typeof(string), () => Standardwert, v => Standardwert = (string?)v) { Category = "Werte", Description = "Ausdruck für neue Zeilen." },
new("Identitaet", typeof(bool), () => Identitaet, v => Identitaet = (bool)v!) { DisplayName = "Identität", Category = "Werte" },
];
}
/// <summary>Das Verhalten beider Fassungen: Objekt wählen, Änderungen melden.</summary>
internal static void Verdrahte(PropertyGrid raster, ComboBox objekt, Button vorschau, TextBlock status)
{
var spalte = new Tabellenspalte();
objekt.ItemsSource = Objekte;
objekt.SelectionChanged += (_, _) => raster.SelectedObject = objekt.SelectedIndex == 1 ? spalte : vorschau;
objekt.SelectedIndex = 0;
raster.PropertyValueChanged += (_, e) =>
status.Text = $"{e.Property.DisplayName}: {PropertyGrid.Format(e.OldValue)} → {PropertyGrid.Format(e.NewValue)}";
}
public override UIElement Baue()
{
var objekt = new ComboBox { MinWidth = 160 };
var vorschau = new Button { Content = "Vorschau" };
var status = new TextBlock { Text = "Noch nichts geändert." };
var raster = new PropertyGrid { Width = 360, Height = 420 };
Verdrahte(raster, objekt, vorschau, status);
var links = new StackPanel { Spacing = 8, Children = { objekt, raster, status } };
var flaeche = new Border { Padding = new Thickness(24), Child = vorschau, VerticalAlignment = VerticalAlignment.Top };
return new StackPanel { Orientation = Orientation.Horizontal, Spacing = 16, Children = { links, flaeche } };
}
}