I'm trying out Avalonia with a little prototype application and having an issue. I have a ListBox that is bound to an ObservableCollection of the view model. I have some Textboxes that update their values based on the selection in the ListBox. I have TwoWay binding setup on the text boxes. When clicking on the different items in the Listbox the text boxes update their values correctly. However, when I try and update the value in the text box it does not update the selected item in the ListBox. I have ported this code to a WPF application and it just works as expected. I'm wondering if I'm missing something specific about how Avalonia is supposed to work. If someone can show me what needs to be done or point me in a direction which will allow me to solve this issue, I'll be grateful. The code I'm working with is below.
// Friend.cs
namespace FriendOrganizer.Models
public class Friend
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
// FriendDataService.cs
namespace FriendOrganizer.Models
public class FriendDataService : IFriendDataService
public IEnumerable<Friend> GetAll()
yield return new Friend {FirstName = "John", LastName = "Doe"};
yield return new Friend {FirstName = "Jane", LastName = "Doe"};
// IFriendDataService.cs
namespace FriendOrganizer.Models
public interface IFriendDataService
IEnumerable<Friend> GetAll();
// ViewModelBase.cs
namespace FriendOrganizer.UI.ViewModels
public class ViewModelBase : INotifyPropertyChanged
public event PropertyChangedEventHandler? PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
if (propertyName is null) throw new ArgumentNullException(nameof(propertyName));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// MainViewModel.cs
namespace FriendOrganizer.UI.ViewModels
public class MainViewModel : ViewModelBase
private readonly IFriendDataService _friendDataService;
private Friend _selectedFriend;
public Friend SelectedFriend
get => _selectedFriend;
_selectedFriend = value;
OnPropertyChanged();
public ObservableCollection<Friend> Friends { get; }
public MainViewModel(IFriendDataService friendDataService)
_friendDataService = friendDataService;
_selectedFriend = new Friend();
Friends = new ObservableCollection<Friend>();
public void Load()
var friends = _friendDataService.GetAll();
Friends.Clear();
foreach (var friend in friends)
Friends.Add(friend);
// MainWindow.axaml.cs
namespace FriendOrganizer.UI.Views
public class MainWindow : Window
private readonly MainViewModel _viewModel;
public MainWindow()
InitializeComponent();
_viewModel = new MainViewModel(new FriendDataService());
DataContext = _viewModel;
this.AttachDevTools();
Opened += MainWindow_Opened;
private void MainWindow_Opened(object? sender, EventArgs e)
_viewModel.Load();
private void InitializeComponent()
AvaloniaXamlLoader.Load(this);
// MainWindow.axaml
<Window
FontSize="20"
Height="350"
Title="FriendOrganizer.UI"
Width="525"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d"
x:Class="FriendOrganizer.UI.Views.MainWindow"
x:DataType="vm:MainViewModel"
xmlns="https://github.com/avaloniaui"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:FriendOrganizer.UI.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid ColumnDefinitions="200,*">
<ListBox Items="{CompiledBinding Friends}" SelectedItem="{CompiledBinding Path=SelectedFriend, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{CompiledBinding FirstName}" />
<TextBlock Margin="5,0,0,0" Text="{CompiledBinding LastName}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid Grid.Column="1" RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,*">
<Label Content="First Name" Margin="10,10,10,0" />
<TextBox
Grid.Row="1"
Margin="10,0,10,10"
Text="{CompiledBinding SelectedFriend.FirstName,
Mode=TwoWay}" />
<Label
Content="Last Name"
Grid.Row="2"
Margin="10,10,10,0" />
<TextBox
Grid.Row="3"
Margin="10,0"
Text="{CompiledBinding SelectedFriend.LastName,
Mode=TwoWay}" />
<Label
Content="Email"
Grid.Row="4"
Margin="10,10,10,0" />
<TextBox
Grid.Row="5"
Margin="10,0"
Text="{CompiledBinding SelectedFriend.Email,
Mode=TwoWay}" />
</Grid>
</Grid>
</Window>
If I understood your problem, you need to implement INotifyPropertyChanged on Friend class.
In WPF it works most likely because of its "hidden aspect" with implicit property changed notifications:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/9365bb6a-b411-4967-9a03-ae2a810fb215/data-binding-without-inotifypropertychanged?forum=wpf
Which isn't the best way of doing bindings because of possible memory leaks:
https://stackoverflow.com/questions/18542940/can-bindings-create-memory-leaks-in-wpf
If I understood your problem, you need to implement INotifyPropertyChanged on Friend class.
In WPF it works most likely because of its "hidden aspect" with implicit property changed notifications:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/9365bb6a-b411-4967-9a03-ae2a810fb215/data-binding-without-inotifypropertychanged?forum=wpf
Which isn't the best way of doing bindings because of possible memory leaks:
https://stackoverflow.com/questions/18542940/can-bindings-create-memory-leaks-in-wpf