In my Avalonia app using the MVVM Community Toolkit, I need to dynamically create a ComboBox from code-behind, having it data-bound to a collection of a subclass of a class that encapsulates properties that describe the ComboBox's selection. The displayed and ToolTip text change as new languages are selected (language selection code is omitted here and replaced with something simpler), and the selected value is of an enum type instead of a string. I cannot get the change handler to call when a new value is selected.
I created a simple app to isolate the problem; code follows.
DropDownOption.cs:
public partial class DropDownOption : ObservableObject {
public FruitType Fruit { get; set; } = FruitType.None;
[ObservableProperty]
protected string _fruitName = string.Empty;
[ObservableProperty]
protected string _toolTipText = string.Empty;
}
public enum FruitType {
Apple,
Orange,
Banana,
None
}
DynaCBXVM.cs
public partial class DynaCBXVM : ObservableObject {
[ObservableProperty]
private FruitType _selectedFruit;
public ObservableCollection<DropDownOption> FruitOptions { get; set; } = [];
public DynaCBXVM() {
FruitOptions.Add(new DropDownOption { Fruit = FruitType.Banana, FruitName = "Cavendish", ToolTipText = "Most common" });
FruitOptions.Add(new DropDownOption { Fruit = FruitType.Apple, FruitName = "Macintosh", ToolTipText = "Also a computer" });
FruitOptions.Add(new DropDownOption { Fruit = FruitType.Orange, FruitName = "Navel", ToolTipText = "Also a body part" });
Debug.WriteLine("And off we go...");
}
partial void OnSelectedFruitChanged(FruitType oldValue, FruitType newValue) {
// Never gets here
Debug.WriteLine($"Unselecting {oldValue} and selecting {newValue}");
}
}
DynaCBX.axaml
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ManualCollectionBindingTest.Views.DynaCBX">
<StackPanel x:Name="stpDynamicCBXes" />
</UserControl>
DynaCBX.axaml.cs
public partial class DynaCBX : UserControl {
public DynaCBX() {
InitializeComponent();
var comBox = new ComboBox {
[!ComboBox.ItemsSourceProperty] = new Binding("FruitOptions"),
[!ComboBox.SelectedValueProperty] = new Binding("SelectedFruit", BindingMode.TwoWay),
[!ComboBox.SelectedValueBindingProperty] = new Binding("Fruit"),
[!ComboBox.DisplayMemberBindingProperty] = new Binding("FruitName"),
Margin = new Thickness(100)
};
comBox.ItemTemplate = new FuncDataTemplate<DropDownOption>((item, _) => {
var optionTextBox = new TextBlock {
[!TextBlock.TextProperty] = new Binding("FruitName")
};
if (item != null && !string.IsNullOrEmpty(item.ToolTipText)) {
ToolTip.SetTip(optionTextBox, item.ToolTipText);
}
return optionTextBox;
});
stpDynamicCBXes.Children.Add(comBox);
DataContext = new DynaCBXVM { SelectedFruit = FruitType.Apple }; // I know, I know…
}
}
Before anyone asks, I can't use XAML files that contain the ComboBoxes. If I could, and I omitted the ToolTip for the options, their XAML would look like this:
<ComboBox ItemsSource="{Binding FruitOptions}"
SelectedValue="{Binding SelectedFruit}"
SelectedValueBinding="{Binding Fruit}"
DisplayMemberBinding="{Binding FruitName}" />
It works pretty well, as pictured above, it just doesn't indicate when the selection changes. Also, it does not start up with "Macintosh" selected; it's unselected instead. I noticed these error messages in the "Debug" window:
[Binding]An error occurred binding 'SelectedValueBinding' to 'Fruit' at 'Fruit': 'Could not find a matching property accessor for 'Fruit' on 'ManualCollectionBindingTest.ViewModels.DynaCBXVM'.' (ComboBox #16468652)
[Binding]An error occurred binding 'DisplayMemberBinding' to 'FruitName' at 'FruitName': 'Could not find a matching property accessor for 'FruitName' on 'ManualCollectionBindingTest.ViewModels.DynaCBXVM'.' (ComboBox #16468652)
Why is it looking for Fruit and FruitName to be properties of DynaCBXVM, when they're properties of DropDownOption?
Thanks in advance for how to fix this.

