---
name: avalonia-data-binding
description: Comprehensive guide to data binding patterns in Avalonia for AI agents.
license: MIT
compatibility: opencode
metadata:
audience: avalonia-developers
framework: avalonia
---
# Data Binding in Avalonia
Comprehensive guide to data binding patterns in Avalonia for AI agents.
## What I do
- Guide implementation of ViewModels with ObservableObject base class
- Show how to create observable properties with [ObservableProperty] attribute
- Demonstrate command patterns with [RelayCommand] including async and CanExecute
- Explain View-ViewModel mapping using DataTemplates (critical for navigation)
- Show dependency injection patterns for passing services to ViewModels
## When to use me
Use this skill when you need to:
- Create new ViewModels for Avalonia views
- Implement observable properties that notify the UI of changes
- Add commands to handle user interactions (button clicks, etc.)
- Set up navigation patterns with DataTemplates and ContentControl
# Data Binding in Avalonia
Comprehensive guide to data binding patterns in Avalonia for AI agents.
## Binding Modes
### OneWay Binding
```xml
```
### TwoWay Binding
```xml
```
**ViewModel:**
```csharp
[ObservableProperty]
private string _userName = "";
[ObservableProperty]
private double _volume = 50;
[ObservableProperty]
private bool _isEnabled = true;
```
### OneTime Binding
```xml
```
### OneWayToSource Binding
```xml
```
### When to use each
Use:
- **OneWay**: Display data that changes infrequently
- **TwoWay**: User input controls (TextBox, Slider, CheckBox)
- **OneTime**: Static data that won't change after load
- **OneWayToSource**: When UI updates ViewModel but not the other way
## Binding Paths
### Simple Property
```xml
```
```csharp
[ObservableProperty]
private string _name = "John";
```
### Nested Property
```xml
```
```csharp
[ObservableProperty]
private Person _person = new();
public class Person
{
public Address Address { get; set; } = new();
}
public class Address
{
public string Street { get; set; } = "";
}
```
### Collection Indexer
```xml
```
```csharp
public ObservableCollection Items { get; } = new();
public ObservableCollection Users { get; } = new();
```
### Attached Property
```xml
```
### Current Item
```xml
```
## Binding Sources
### DataContext (Default)
```xml
```
### Element Binding
```xml
```
### Relative Source - Parent
```xml
```
### Relative Source - Self
```xml
```
### Static Resource
```xml
```
### Static Property
```xml
```
## Value Converters
### Built-in Converters
#### Boolean Converters
```xml
```
#### Object Converters
```xml
```
### Custom Converter
**Define Converter:**
```csharp
public class BoolToColorConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is bool boolValue)
{
return boolValue ? Brushes.Green : Brushes.Red;
}
return Brushes.Gray;
}
public object? ConvertBack(object? va, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
```
**Register in Resources:**
```xml
```
**Use Converter:**
```xml
```
### Converter with Parameter
```xml
```
### Format Specifiers
#### Numeric Formats
```xml
```
#### Date/Time Formats
```xml
```
### Escaping Braces
```xml
```
## Compiled Bindings
### Why Compiled Bindings?
- **Performance**: 2-3x faster than reflection-based bindings
- **Type Safety**: Compile-time errors instead of runtime
- **IntelliSense**: Better IDE support
- **Required**: For Avalon with `AvaloniaUseCompiledBindingsByDefault`
### Enabling Compiled Bindings
**Project File:**
```xml
true
```
**AXAML:**
```xml
```
### Compiled Binding Syntax
```xml
```
### DataType for Collections
```xml
```
### DataType Inheritance
```xml
```
## Common Patterns
### Binding to Commands```xml
```
```csharp
[RelayCommand]
private void Save()
{
// Save logic
}
[RelayCommand]
private void Delete(object? parameter)
{
if (parameter is Item item)
{
// Delete item
}
}
```
### Binding to Collections
```xml
```
```csharp
public ObservableCollection- Items { get; } = new();
[ObservableProperty]
private Item? _selectedItem;
```
### Binding to Enums
```xml
```
```csharp
public enum Status { Active, Inactive, Pending }
public IEnumerable AllStatuses => Enum.GetValues();
[ObservableProperty]
private Status _currentStatus = Status.Active;
```
### Conditional Visibility
```xml
```
### Multi-Binding (Alternative Approaches)
**Option 1: Computed Property**
```csharp
[ObservableProperty]
private string _firstName = "";
[ObservableProperty]
private string _lastName = "";
public string FullName => $"{FirstName} {LastName}";
partial void OnFirstNameChanged(string value) => OnPropertyChanged(nameof(FullName));
partial void OnLastNameChanged(string value) => OnPropertyChanged(nameof(FullName));
```
```xml
```
**Option 2: Converter**
```xml
```
### Binding with Fallback
```xml
```
### Binding with TargetNullValue
```xml
```
## Best Practices
1. **Always set x:DataType** for compiled bindings
2. **Use TwoWay explicitly** for input controls
3. **Use OneTimetic data to improve performance
4. **Prefer computed properties** over complex converters
5. **Use StringFormat** for simple formatting
6. **Use converters** for complex transformations
7. **Bind to commands** instead of event handlers
8. **Use ObservableCollection** for dynamic lists
9. **Implement INotifyPropertyChanged** (via CommunityToolkit.Mvvm)
10. **Test bindings** with design-time data
## Common Mistakes
❌ **DatePicker Binding Type Mismatch**
```csharp
[ObservableProperty]
private DateTime _selectedDate = DateTime.Now; // ❌ InvalidCastException
```
✅ **Correct**
```csharp
[ObservableProperty]
private DateTimeOffset? _selectedDate = DateTimeOffset.Now; // ✅ Use DateTimeOffset?
```
❌ **Missing Mode for input**
```xml
```
✅ **Correct**
```xml
```
❌ **Forgetting x:DataType**
```xml
```
✅ **Correct**
```xml
```
❌ **Not notifying property changes**
```csharp
private string _name;
public string Name
{
get => _name;
set => _name = value; // UI won't update!
}
```
✅ **Correct**
```csharp
[ObservableProperty]
private string _name = ""; // Generates proper notification
```