Primary APIs:
TextBox, MaskedTextBox, NumericUpDown, DatePicker, TimePicker, CheckBox, RadioButton, ComboBox, Slider, ToggleSwitchICommand, Button.Command, hotkeys/gesturesDataValidationErrors, binding validation hooksAutomationPropertiesReference docs:
22-validation-pipeline-and-data-errors.md58-textbox-editing-clipboard-undo-and-input-options.md23-accessibility-and-automation.md60-automation-properties-and-attached-behavior-patterns.md| HTML element/idiom | Avalonia control/pattern |
|---|---|
<input type="text"> |
TextBox Text |
<input type="password"> |
TextBox PasswordChar / RevealPassword |
<input type="number"> |
NumericUpDown |
<input type="date"> |
DatePicker |
<input type="time"> |
TimePicker |
<input type="checkbox"> |
CheckBox |
<input type="radio"> |
RadioButton |
<select> |
ComboBox |
<textarea> |
TextBox AcceptsReturn="True" TextWrapping="Wrap" |
<label for="..."> |
Label Target="{Binding ElementName=...}" or adjacent semantic labeling |
| HTML validation idiom | Avalonia mapping |
|---|---|
required, minlength, pattern |
viewmodel/domain validation + binding validation |
:invalid pseudo-state |
DataValidationErrors template/styles |
| form submit prevention | command CanExecute and validation state |
Pattern:
| Web accessibility idiom | Avalonia mapping |
|---|---|
aria-label |
AutomationProperties.Name |
aria-describedby |
AutomationProperties.HelpText |
id for automation |
AutomationProperties.AutomationId |
| landmark role intent | logical layout + explicit control semantics and automation metadata |
HTML/CSS:
<form class="settings">
<label for="displayName">Display Name</label>
<input id="displayName" type="text" placeholder="Jane Doe">
<label for="role">Role</label>
<select id="role">
<option>Admin</option>
<option>Editor</option>
</select>
<button class="primary">Save</button>
</form>
.settings {
display: grid;
grid-template-columns: 180px 1fr;
gap: 10px 12px;
}
.settings input, .settings select {
border: 1px solid #2a3348;
border-radius: 8px;
padding: 10px 12px;
}
.settings button.primary {
grid-column: 2;
justify-self: start;
}
Avalonia:
<Grid ColumnDefinitions="180,*"
RowDefinitions="Auto,Auto,Auto"
ColumnSpacing="12"
RowSpacing="10">
<TextBlock Grid.Row="0" Grid.Column="0" Text="Display Name" VerticalAlignment="Center" />
<TextBox Grid.Row="0" Grid.Column="1"
Text="{CompiledBinding DisplayName}"
Watermark="Jane Doe" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="Role" VerticalAlignment="Center" />
<ComboBox Grid.Row="1" Grid.Column="1"
ItemsSource="{CompiledBinding Roles}"
SelectedItem="{CompiledBinding SelectedRole}" />
<Button Grid.Row="2" Grid.Column="1"
HorizontalAlignment="Left"
Classes="primary"
Content="Save"
Command="{CompiledBinding SaveCommand}" />
</Grid>
HTML:
<form class="profile" novalidate>
<label>Email</label>
<input type="email" required>
<label>Age</label>
<input type="number" min="0" max="120">
<button type="submit">Save</button>
</form>
Avalonia XAML:
<StackPanel Spacing="10" x:DataType="vm:ProfileViewModel">
<TextBlock Text="Email" />
<TextBox Text="{CompiledBinding Email}" Watermark="name@example.com" />
<TextBlock Text="Age" />
<NumericUpDown Value="{CompiledBinding Age}" Minimum="0" Maximum="120" />
<CheckBox IsChecked="{CompiledBinding AcceptTerms}" Content="Accept terms" />
<Button Content="Save"
Command="{CompiledBinding SaveCommand}"
IsEnabled="{CompiledBinding CanSave}" />
</StackPanel>
Minimal viewmodel sketch:
public sealed class ProfileViewModel
{
public string? Email { get; set; }
public decimal Age { get; set; }
public bool AcceptTerms { get; set; }
public bool CanSave =>
!string.IsNullOrWhiteSpace(Email) &&
Age is >= 0 and <= 120 &&
AcceptTerms;
}
using Avalonia.Controls;
var profileForm = new StackPanel
{
Spacing = 10
};
profileForm.Children.Add(new TextBlock { Text = "Email" });
profileForm.Children.Add(new TextBox { Watermark = "name@example.com" });
profileForm.Children.Add(new TextBlock { Text = "Age" });
profileForm.Children.Add(new NumericUpDown
{
Minimum = 0,
Maximum = 120
});
profileForm.Children.Add(new CheckBox { Content = "Accept terms" });
profileForm.Children.Add(new Button { Content = "Save" });
Dispatcher.UIThread.TextBox password behavior differs from web field.
PasswordChar and optional RevealPassword; do not bind plaintext mirrors unless required.