# PropertyGrid Advanced Example - Technical Documentation ## Architecture Overview The Advanced Example demonstrates a production-ready PropertyGrid implementation with enterprise-level features. ## Class Hierarchy ``` AdvancedConfiguration (INotifyPropertyChanged) ├── Server Configuration │ ├── ServerName (string, validated) │ ├── MaxConnections (int, range: 1-1000) │ ├── ConnectionType (enum) │ └── RequiresCertificate (computed, read-only) ├── Logging │ ├── EnableLogging (bool) │ ├── LogLevel (enum) │ └── LogFilePath (string, advanced) ├── Network │ ├── Timeout (TimeSpan) │ └── NetworkSettings (nested object) │ ├── Hostname (string, required) │ ├── Port (int, range: 1-65535) │ ├── UseProxy (bool) │ └── ProxyAddress (string) ├── Database │ └── DatabaseSettings (nested object) │ ├── ConnectionString (string, required) │ ├── Provider (enum) │ ├── CommandTimeout (int) │ ├── EnableRetry (bool) │ └── MaxRetryCount (int, range: 1-10) ├── Security │ ├── ApiKey (string, password) │ └── AllowedIPs (List) ├── Performance │ ├── CompressionLevel (int, range: 0-9) │ └── CacheSizeMB (int, range: 10-1024) └── Metadata (all read-only) ├── CreatedDate (DateTime) ├── LastModified (DateTime) └── ConfigurationId (Guid) ``` ## Property Types Reference ### Basic Types | Type | Example Property | Validation | Category | |------|------------------|------------|----------| | `string` | ServerName | Required, Length(3-50) | Server Configuration | | `int` | MaxConnections | Range(1-1000) | Server Configuration | | `bool` | EnableLogging | None | Logging | | `decimal` | Price (QuickStart) | None | Financial | ### Advanced Types | Type | Example Property | Notes | Category | |------|------------------|-------|----------| | `TimeSpan` | Timeout | Duration selection | Network | | `DateTime` | CreatedDate | Date/time picker | Metadata | | `Guid` | ConfigurationId | Unique identifier | Metadata | | `List` | AllowedIPs | Collection editing | Security | ### Enum Types | Enum | Values | Description Support | Category | |------|--------|---------------------|----------| | ConnectionType | Http, Ssl, Tcp, Custom | ✅ | Server Configuration | | LogLevel | Trace, Debug, Info, Warning, Error, Critical, None | ❌ | Logging | | DatabaseProvider | SqlServer, PostgreSQL, MySQL, SQLite, Oracle | ✅ | Database | ### Nested Objects | Object | Properties | Implements INPC | Category | |--------|-----------|-----------------|----------| | NetworkSettings | 4 properties | ✅ | Network | | DatabaseSettings | 5 properties | ✅ | Database | ## Validation Rules ### String Validation ```csharp [Required(ErrorMessage = "Server name is required")] [StringLength(50, MinimumLength = 3, ErrorMessage = "Server name must be between 3 and 50 characters")] public string ServerName { get; set; } ``` ### Numeric Range Validation ```csharp [Range(1, 1000, ErrorMessage = "Max connections must be between 1 and 1000")] public int MaxConnections { get; set; } ``` ### Required Field Validation ```csharp [Required] public string Hostname { get; set; } ``` ## Change Notification System ### Implementation Pattern ```csharp private string _serverName = "Production-Server-01"; public string ServerName { get => _serverName; set => SetProperty(ref _serverName, value); } protected bool SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return false; field = value; LastModified = DateTime.Now; // Auto-update metadata OnPropertyChanged(propertyName); return true; } ``` ### Cascading Updates When `ConnectionType` changes, `RequiresCertificate` automatically updates: ```csharp public ConnectionType ConnectionType { get => _connectionType; set { if (SetProperty(ref _connectionType, value)) { OnPropertyChanged(nameof(RequiresCertificate)); // Cascade } } } public bool RequiresCertificate => ConnectionType == ConnectionType.Ssl; ``` ## Computed Properties Computed properties derive their value from other properties: ```csharp [Display(Name = "Requires Certificate", Order = 4)] [Category("Server Configuration")] [ReadOnly(true)] public bool RequiresCertificate => ConnectionType == ConnectionType.Ssl; ``` **Benefits:** - Always in sync with source properties - No manual updates needed - Marked as read-only - Displayed in PropertyGrid but not editable ## Category Organization Categories organize properties logically: | Category | Purpose | Property Count | |----------|---------|----------------| | Server Configuration | Core server settings | 4 | | Logging | Logging and diagnostics | 3 | | Network | Network connectivity | 2 (+ nested) | | Database | Database connection | 1 (nested) | | Security | Authentication & access | 2 | | Performance | Optimization settings | 2 | | Metadata | System information | 3 | ## Property Ordering Properties within categories are ordered using the `Order` attribute: ```csharp [Display(Order = 1)] // First in category [Display(Order = 2)] // Second in category [Display(Order = 3)] // Third in category ``` ## Special Attributes ### PasswordPropertyText Hides sensitive information: ```csharp [PasswordPropertyText(true)] public string ApiKey { get; set; } ``` ### EditorBrowsable Groups advanced properties: ```csharp [EditorBrowsable(EditorBrowsableState.Advanced)] public string LogFilePath { get; set; } ``` ### ReadOnly Prevents property editing: ```csharp [ReadOnly(true)] public DateTime CreatedDate { get; set; } ``` ## Data Binding in XAML ### Setting DataContext ```csharp // In MainWindow.axaml.cs public MainWindow() { InitializeComponent(); DataContext = new AdvancedConfiguration(); } ``` ### PropertyGrid Binding ```xml ``` **Key Points:** - `x:DataType` enables compiled bindings (.NET 10 requirement) - `{Binding}` binds to the entire DataContext - `ShowCategories` enables category grouping - `ShowDescriptions` displays property descriptions ## Performance Considerations ### Efficient Change Notifications ```csharp protected bool SetProperty(ref T field, T value, ...) { // Early exit if value hasn't changed if (EqualityComparer.Default.Equals(field, value)) return false; // Only notify if changed field = value; OnPropertyChanged(propertyName); return true; } ``` ### Lazy Initialization ```csharp private DatabaseSettings _databaseSettings = new(); // Initialized once public DatabaseSettings DatabaseSettings => _databaseSettings; ``` ## Testing Scenarios ### Validation Testing 1. Enter invalid server name (< 3 chars or > 50 chars) 2. Set MaxConnections outside range (< 1 or > 1000) 3. Leave required fields empty ### Change Notification Testing 1. Change ConnectionType to/from Ssl 2. Observe RequiresCertificate updates automatically 3. Note LastModified timestamp changes ### Nested Object Testing 1. Expand NetworkSettings 2. Modify nested properties 3. Verify changes propagate correctly ## Extension Points ### Adding New Properties 1. Add private backing field 2. Create public property with notifications 3. Add appropriate attributes 4. Assign to category ### Adding New Categories Simply use a new category name: ```csharp [Category("New Category Name")] public string NewProperty { get; set; } ``` ### Custom Validation Implement `IDataErrorInfo` or `INotifyDataErrorInfo`: ```csharp public class AdvancedConfiguration : INotifyPropertyChanged, IDataErrorInfo { public string Error => string.Empty; public string this[string columnName] { get { // Return validation error for property return string.Empty; } } } ``` ## Common Patterns ### ✅ DO - Use INotifyPropertyChanged for all mutable properties - Add descriptions to all properties - Organize properties into logical categories - Validate user input - Use appropriate data types - Mark computed properties as read-only ### ❌ DON'T - Skip property change notifications - Mix unrelated properties in same category - Use generic category names like "Properties" - Forget validation on user input - Use string for structured data (use enums or objects) - Make computed properties editable ## Summary The Advanced Example demonstrates: - ✅ 25+ properties across 7 categories - ✅ 2 levels of nested objects - ✅ Full INotifyPropertyChanged implementation - ✅ Comprehensive validation - ✅ Computed properties - ✅ Multiple data types - ✅ Production-ready code structure This serves as a blueprint for real-world PropertyGrid implementations.