- Improved PropertyGrid.axaml formatting and control styles; ensured spinner buttons are always visible and ColorPicker layouts are flexible; disabled horizontal scrolling in property list. - Reformatted property editors and group/category display for clarity. - Made all value converters sealed, added XML docs, and updated ConvertBack to throw NotImplementedException where unsupported. - Enhanced search logic to use StringComparison.OrdinalIgnoreCase. - Minor code style fixes (e.g., char literals for string checks). - Removed default value assignment for _useProxy in AdvancedConfiguration.cs. - Updated Program.cs in examples to use sealed Program classes. - Added PropertyGrid.slnx to organize solution and projects.
411 lines
12 KiB
C#
411 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Runtime.CompilerServices;
|
|
using Avalonia.Media;
|
|
|
|
namespace AdvancedExample.Models;
|
|
|
|
/// <summary>
|
|
/// Advanced example demonstrating complex PropertyGrid features
|
|
/// including nested objects, collections, validation, and dynamic properties
|
|
/// </summary>
|
|
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<string> _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<string> 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<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
|
|
{
|
|
if (EqualityComparer<T>.Default.Equals(field, value))
|
|
return false;
|
|
|
|
field = value;
|
|
LastModified = DateTime.Now;
|
|
OnPropertyChanged(propertyName);
|
|
return true;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Network settings nested object
|
|
/// </summary>
|
|
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<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
|
|
{
|
|
if (EqualityComparer<T>.Default.Equals(field, value))
|
|
return false;
|
|
|
|
field = value;
|
|
OnPropertyChanged(propertyName);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Database settings nested object
|
|
/// </summary>
|
|
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<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
|
|
{
|
|
if (EqualityComparer<T>.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
|
|
}
|