Files
PropertyGrid/Examples/QUICK_REFERENCE.md
T
2026-08-10 14:46:18 +02:00

368 lines
7.0 KiB
Markdown

# PropertyGrid Quick Reference Guide
## Essential Attributes
### Display Attribute
Controls property appearance in PropertyGrid:
```csharp
[Display(
Name = "Display Name", // Shown in UI
Description = "Property help", // Tooltip/description
Order = 1 // Sort order in category
)]
public string MyProperty { get; set; }
```
### Category Attribute
Groups related properties:
```csharp
[Category("Server Settings")]
public string ServerName { get; set; }
```
### ReadOnly Attribute
Makes property non-editable:
```csharp
[ReadOnly(true)]
public string ComputedValue { get; set; }
```
## Validation Attributes
### Required
```csharp
[Required(ErrorMessage = "This field is required")]
public string ServerName { get; set; }
```
### Range
```csharp
[Range(1, 100, ErrorMessage = "Value must be between 1 and 100")]
public int Connections { get; set; }
```
### StringLength
```csharp
[StringLength(50, MinimumLength = 3,
ErrorMessage = "Length must be between 3 and 50")]
public string Name { get; set; }
```
### RegularExpression
```csharp
[RegularExpression(@"^\d{3}-\d{2}-\d{4}$",
ErrorMessage = "Invalid format")]
public string SSN { get; set; }
```
## Special Attributes
### PasswordPropertyText
Hides text input:
```csharp
[PasswordPropertyText(true)]
public string Password { get; set; }
```
### EditorBrowsable
Controls visibility of advanced properties:
```csharp
[EditorBrowsable(EditorBrowsableState.Advanced)]
public string AdvancedSetting { get; set; }
```
## INotifyPropertyChanged Pattern
### Basic Implementation
```csharp
public class MyModel : INotifyPropertyChanged
{
private string _name = string.Empty;
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
```
### Helper Method Pattern
```csharp
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;
}
// Usage
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
```
## Supported Property Types
### Basic Types
- `string` - Text input
- `int`, `long`, `short` - Numeric input
- `double`, `float`, `decimal` - Decimal input
- `bool` - Checkbox
- `DateTime` - Date/time picker
- `TimeSpan` - Duration input
- `Guid` - GUID input
- `Uri` - URL input
### Complex Types
- `enum` - Dropdown list
- Nested objects - Expandable group
- `List<T>` - Collection editor (if supported)
### Nullable Types
All value types can be nullable:
```csharp
public int? OptionalNumber { get; set; }
public DateTime? OptionalDate { get; set; }
```
## Enum with Descriptions
```csharp
public enum Status
{
[Description("Not yet started")]
NotStarted,
[Description("Currently in progress")]
InProgress,
[Description("Successfully completed")]
Completed,
[Description("Failed with errors")]
Failed
}
```
## Nested Objects
```csharp
public class Configuration
{
[Display(Name = "Database Settings")]
[Category("Database")]
public DatabaseSettings Database { get; set; } = new();
}
public class DatabaseSettings
{
[Display(Name = "Server")]
public string Server { get; set; } = "localhost";
[Display(Name = "Port")]
[Range(1, 65535)]
public int Port { get; set; } = 5432;
}
```
## XAML Setup
### Basic PropertyGrid
```xml
<Window xmlns:pg="using:Avalonia.PropertyGrid.Controls"
xmlns:models="using:YourNamespace.Models"
x:DataType="models:YourModel">
<pg:PropertyGrid SelectedObject="{Binding}"
ShowCategories="True"
ShowDescriptions="True" />
</Window>
```
### Code-Behind
```csharp
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new YourModel();
}
}
```
## Computed Properties
Properties that derive from other properties:
```csharp
private bool _isEnabled;
public bool IsEnabled
{
get => _isEnabled;
set
{
if (SetProperty(ref _isEnabled, value))
{
OnPropertyChanged(nameof(StatusText));
}
}
}
[ReadOnly(true)]
public string StatusText => IsEnabled ? "Enabled" : "Disabled";
```
## Common Patterns
### Server Configuration
```csharp
[Display(Name = "Server Address", Order = 1)]
[Category("Connection")]
[Required]
public string ServerAddress { get; set; } = "localhost";
[Display(Name = "Port", Order = 2)]
[Category("Connection")]
[Range(1, 65535)]
public int Port { get; set; } = 8080;
[Display(Name = "Use SSL", Order = 3)]
[Category("Security")]
public bool UseSsl { get; set; } = true;
```
### Credentials
```csharp
[Display(Name = "Username")]
[Category("Authentication")]
[Required]
public string Username { get; set; } = string.Empty;
[Display(Name = "Password")]
[Category("Authentication")]
[PasswordPropertyText(true)]
public string Password { get; set; } = string.Empty;
```
### File Paths
```csharp
[Display(Name = "Log Directory")]
[Category("Logging")]
[EditorBrowsable(EditorBrowsableState.Advanced)]
public string LogDirectory { get; set; } = @"C:\Logs\";
```
## Tips & Tricks
### 1. Property Order Gaps
Use gaps (10, 20, 30) for easy insertion:
```csharp
[Display(Order = 10)] // Easy to insert Order = 15 later
[Display(Order = 20)]
[Display(Order = 30)]
```
### 2. Category Naming
Use clear, hierarchical names:
- ✅ "Server Configuration"
- ✅ "Database / Connection"
- ❌ "Misc"
- ❌ "Settings"
### 3. Meaningful Descriptions
```csharp
// ❌ Bad
[Display(Description = "The timeout")]
// ✅ Good
[Display(Description = "Connection timeout in seconds (1-300)")]
```
### 4. Validation Messages
```csharp
// ❌ Generic
[Required(ErrorMessage = "Required")]
// ✅ Specific
[Required(ErrorMessage = "Server name is required for connection")]
```
### 5. Default Values
Always provide sensible defaults:
```csharp
public int MaxConnections { get; set; } = 100; // ✅ Good default
public int Timeout { get; set; } = 30; // ✅ Reasonable
public string Server { get; set; } = string.Empty; // ✅ Safe default
```
## Debugging
### Check Binding
Add this to see binding errors:
```csharp
.LogToTrace(areas: new[] {
LogArea.Binding,
LogArea.Property
})
```
### Verify DataContext
```csharp
public MainWindow()
{
InitializeComponent();
var model = new MyModel();
DataContext = model;
// Verify
System.Diagnostics.Debug.WriteLine($"DataContext: {DataContext?.GetType().Name}");
}
```
## Performance
### Lazy Loading
```csharp
private DatabaseSettings? _database;
public DatabaseSettings Database => _database ??= new DatabaseSettings();
```
### Efficient Notifications
```csharp
// Only notify if value actually changed
if (_field == value) return;
```
## See Also
- [QuickStartExample](../QuickStartExample/) - Basic usage
- [AdvancedExample](../AdvancedExample/) - Complex scenarios
- [Technical Documentation](./TECHNICAL.md) - Deep dive
---
**Need help?** Check the examples or review the PropertyGrid source code!