using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Runtime.CompilerServices; using Avalonia.Media; namespace AdvancedExample.Models; /// /// Advanced example demonstrating complex PropertyGrid features /// including nested objects, collections, validation, and dynamic properties /// public class AdvancedConfiguration : INotifyPropertyChanged { private string _serverName = "Production-Server-01"; private int _maxConnections = 100; private ConnectionType _connectionType = ConnectionType.Ssl; private bool _enableLogging = true; private LogLevel _logLevel = LogLevel.Information; private TimeSpan _timeout = TimeSpan.FromSeconds(30); private DatabaseSettings _databaseSettings = new(); private NetworkSettings _networkSettings = new(); private List _allowedIPs = new() { "192.168.1.100", "10.0.0.50" }; private Color _themeColor = Colors.DodgerBlue; private Priority _priority = Priority.Normal; #region Basic Properties with Validation [Display(Name = "Server Name", Description = "The name of the server", Order = 1)] [Category("Server Configuration")] [Required(ErrorMessage = "Server name is required")] [StringLength(50, MinimumLength = 3, ErrorMessage = "Server name must be between 3 and 50 characters")] public string ServerName { get => _serverName; set => SetProperty(ref _serverName, value); } [Display(Name = "Max Connections", Description = "Maximum number of concurrent connections", Order = 2)] [Category("Server Configuration")] [Range(1, 1000, ErrorMessage = "Max connections must be between 1 and 1000")] public int MaxConnections { get => _maxConnections; set => SetProperty(ref _maxConnections, value); } [Display(Name = "Connection Type", Description = "Type of connection security", Order = 3)] [Category("Server Configuration")] public ConnectionType ConnectionType { get => _connectionType; set { if (SetProperty(ref _connectionType, value)) { OnPropertyChanged(nameof(RequiresCertificate)); } } } [Display(Name = "Requires Certificate", Description = "Whether SSL certificate is required", Order = 4)] [Category("Server Configuration")] [ReadOnly(true)] public bool RequiresCertificate => ConnectionType == ConnectionType.Ssl; #endregion #region Logging Configuration [Display(Name = "Enable Logging", Description = "Enable application logging", Order = 10)] [Category("Logging")] public bool EnableLogging { get => _enableLogging; set => SetProperty(ref _enableLogging, value); } [Display(Name = "Log Level", Description = "Minimum log level to record", Order = 11)] [Category("Logging")] public LogLevel LogLevel { get => _logLevel; set => SetProperty(ref _logLevel, value); } [Display(Name = "Log File Path", Description = "Full path to the log file", Order = 12)] [Category("Logging")] [EditorBrowsable(EditorBrowsableState.Advanced)] public string LogFilePath { get; set; } = @"C:\Logs\application.log"; #endregion #region Network Configuration [Display(Name = "Connection Timeout", Description = "Timeout for network connections", Order = 20)] [Category("Network")] public TimeSpan Timeout { get => _timeout; set => SetProperty(ref _timeout, value); } [Display(Name = "Network Settings", Description = "Advanced network configuration", Order = 21)] [Category("Network")] public NetworkSettings NetworkSettings { get => _networkSettings; set => SetProperty(ref _networkSettings, value); } #endregion #region Database Configuration [Display(Name = "Database Settings", Description = "Database connection settings", Order = 30)] [Category("Database")] public DatabaseSettings DatabaseSettings { get => _databaseSettings; set => SetProperty(ref _databaseSettings, value); } #endregion #region Advanced Settings [Display(Name = "API Key", Description = "Secret API key for authentication", Order = 40)] [Category("Security")] [PasswordPropertyText(true)] public string ApiKey { get; set; } = "sk_live_abc123def456"; [Display(Name = "Allowed IP Addresses", Description = "List of allowed IP addresses", Order = 41)] [Category("Security")] public List AllowedIPs { get => _allowedIPs; set => SetProperty(ref _allowedIPs, value); } [Display(Name = "Compression Level", Description = "Data compression level (0-9)", Order = 42)] [Category("Performance")] [Range(0, 9)] public int CompressionLevel { get; set; } = 5; [Display(Name = "Cache Size (MB)", Description = "Memory cache size in megabytes", Order = 43)] [Category("Performance")] [Range(10, 1024)] public int CacheSizeMB { get; set; } = 256; [Display(Name = "Processing Priority", Description = "Priority level for background processing tasks", Order = 44)] [Category("Performance")] public Priority Priority { get => _priority; set => SetProperty(ref _priority, value); } [Display(Name = "Theme Color", Description = "Application theme accent color", Order = 44)] [Category("Appearance")] public Color ThemeColor { get => _themeColor; set { if (SetProperty(ref _themeColor, value)) { OnPropertyChanged(nameof(ThemeColorName)); } } } [Display(Name = "Theme Color Name", Description = "Name of the current theme color", Order = 45)] [Category("Appearance")] [ReadOnly(true)] public string ThemeColorName => _themeColor.ToString(); [Display(Name = "Created Date", Description = "Configuration creation date", Order = 50)] [Category("Metadata")] [ReadOnly(true)] public DateTime CreatedDate { get; set; } = DateTime.Now; [Display(Name = "Last Modified", Description = "Last modification date", Order = 51)] [Category("Metadata")] [ReadOnly(true)] public DateTime LastModified { get; set; } = DateTime.Now; [Display(Name = "Configuration ID", Description = "Unique configuration identifier", Order = 52)] [Category("Metadata")] [ReadOnly(true)] public Guid ConfigurationId { get; set; } = Guid.NewGuid(); #endregion #region INotifyPropertyChanged Implementation public event PropertyChangedEventHandler? PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } 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; OnPropertyChanged(propertyName); return true; } #endregion } /// /// Network settings nested object /// public class NetworkSettings : INotifyPropertyChanged { private string _hostname = "api.example.com"; private int _port = 443; private bool _useProxy; private string _proxyAddress = string.Empty; [Display(Name = "Hostname", Description = "Server hostname or IP address")] [Category("Connection")] [Required] public string Hostname { get => _hostname; set => SetProperty(ref _hostname, value); } [Display(Name = "Port", Description = "Server port number")] [Category("Connection")] [Range(1, 65535)] public int Port { get => _port; set => SetProperty(ref _port, value); } [Display(Name = "Use Proxy", Description = "Whether to use a proxy server")] [Category("Proxy")] public bool UseProxy { get => _useProxy; set => SetProperty(ref _useProxy, value); } [Display(Name = "Proxy Address", Description = "Proxy server address")] [Category("Proxy")] public string ProxyAddress { get => _proxyAddress; set => SetProperty(ref _proxyAddress, value); } public event PropertyChangedEventHandler? PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected bool SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return false; field = value; OnPropertyChanged(propertyName); return true; } } /// /// Database settings nested object /// public class DatabaseSettings : INotifyPropertyChanged { private string _connectionString = "Server=localhost;Database=MyApp;"; private DatabaseProvider _provider = DatabaseProvider.PostgreSQL; private int _commandTimeout = 30; private bool _enableRetry = true; private int _maxRetryCount = 3; [Display(Name = "Connection String", Description = "Database connection string")] [Category("Connection")] [Required] public string ConnectionString { get => _connectionString; set => SetProperty(ref _connectionString, value); } [Display(Name = "Provider", Description = "Database provider type")] [Category("Connection")] public DatabaseProvider Provider { get => _provider; set => SetProperty(ref _provider, value); } [Display(Name = "Command Timeout (sec)", Description = "Command timeout in seconds")] [Category("Performance")] [Range(1, 300)] public int CommandTimeout { get => _commandTimeout; set => SetProperty(ref _commandTimeout, value); } [Display(Name = "Enable Retry", Description = "Enable automatic retry on failure")] [Category("Resilience")] public bool EnableRetry { get => _enableRetry; set => SetProperty(ref _enableRetry, value); } [Display(Name = "Max Retry Count", Description = "Maximum number of retry attempts")] [Category("Resilience")] [Range(1, 10)] public int MaxRetryCount { get => _maxRetryCount; set => SetProperty(ref _maxRetryCount, value); } public event PropertyChangedEventHandler? PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected bool SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return false; field = value; OnPropertyChanged(propertyName); return true; } } public enum ConnectionType { [Description("Plain HTTP connection")] Http, [Description("Secure HTTPS/SSL connection")] Ssl, [Description("TCP socket connection")] Tcp, [Description("Custom protocol")] Custom } public enum LogLevel { Trace, Debug, Information, Warning, Error, Critical, None } public enum DatabaseProvider { [Description("Microsoft SQL Server")] SqlServer, [Description("PostgreSQL Database")] PostgreSQL, [Description("MySQL Database")] MySQL, [Description("SQLite Embedded Database")] SQLite, [Description("Oracle Database")] Oracle } public enum Priority { [Description("Low priority - runs when system is idle")] Low, [Description("Normal priority - standard processing")] Normal, [Description("High priority - elevated processing")] High, [Description("Critical priority - immediate processing required")] Critical }