I am trying to make a custom ContentView for a control that works similar to Bootstrap's Navigation Pills.
Here is the code for my custom view.
PillToggle.xaml.cs
public partial class PillToggle : ContentView
{
public PillToggle()
{
InitializeComponent();
this.BindingContext = this;
// BindableLayout.SetItemsSource(this.PillsContainer, this.Pills);
}
public ObservableCollection<Pill> Pills
{
get { return (ObservableCollection<Pill>)GetValue(PillsProperty); }
set { SetValue(PillsProperty, value); }
}
public static readonly BindableProperty PillsProperty =
BindableProperty.Create("Pills", typeof(ObservableCollection<Pill>), typeof(PillToggle), defaultValue: new ObservableCollection<Pill>());
}
PillToggle.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:REDACTED"
x:Class="REDACTED.PillToggle">
<Frame BackgroundColor="#eeeeee" CornerRadius="24" Padding="4" MinimumHeightRequest="48">
<HorizontalStackLayout x:Name="PillsContainer" BindableLayout.ItemsSource="{Binding Pills}" HorizontalOptions="Start" >
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="controls:Pill">
... snip
</DataTemplate>
</BindableLayout.ItemTemplate>
</HorizontalStackLayout>
</Frame>
</ContentView>
Pill.cs
public partial class Pill : ObservableObject
{
[ObservableProperty]
public string? label;
[ObservableProperty]
private bool selected = false;
}
When I try to use this View in a ContentPage, I am unable to Bind the Pills Collection via XAML.
MyPageViewModel.cs
public partial class MyViewModel : ObservableObject
{
//Hard coded for now, but may become dynamic
public IEnumerable<Pill> MyPills { get; } = new List<Pill>()
{
new Pill() { Label = "Test 1" },
new Pill() { Label = "Test 2" }
};
}
MyPage.xaml (Usage)
<controls:PillToggle x:Name="MyToggle" Pills="{Binding MyPills}" >
MyPage.xaml.cs (Constructor)
public MyPage(MyViewModel viewModel)
{
this.BindingContext = viewModel;
InitializeComponent();
}
When I run my app, I don't see any pills. I can see the Views background color, but the HorizontalStackView appears to not be bound to any items.
If I remove the Binding from Xaml, and manually bind in the code behind constructor, it works.
MyToggle.Pills = new ObservableCollection<Controls.Pill>(viewModel.MyPills);
It also works if I manually add the pills like this.
<controls:PillToggle x:Name="MyToggle">
<controls:PillToggle.Pills>
<controls: Pill Label="Test 3" Selected="True" />
<controls: Pill Label="Test 4" />
</controls:PillToggle.Pills>
</controls:PillToggle>
How can I get Binding to work in Xaml for my custom ContentView?