I am trying to use custom control with generic type in BindableProperty like so:
public partial class Overview : ContentView
{
public static readonly BindableProperty AnimalsProperty =
BindableProperty.Create(nameof(AnimalsProperty), typeof(ObservableRangeCollection<IAnimal>), typeof(Overview), null);
public ObservableRangeCollection<IAnimal> Animals
{
get { return (ObservableRangeCollection<IAnimal>)GetValue(AnimalsProperty); }
set { SetValue(AnimalsProperty, value); }
}
}
public interface IAnimal {}
public partial class Dog: ObservableObject, IAnimal {}
DogOverview xaml:
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DogOverview"
>
<Grid>
<local:Overview
Animals="{Binding Dogs}"
/>
</Grid>
</ContentView>
public partial class DogViewModel: ObservableObject
{
[ObservableProperty]
private ObservableRangeCollection<Dog> _dogs = [];
}
And when I use BindableContext in DogOverview
like:
public partial class DogOverview : ContentView
{
public DogOverview(DogViewModel vm)
{
InitializeComponent();
BindingContext = vm;
}
}
There is an error in line BindingContext = vm
: **System.InvalidCastException:** 'Object must implement IConvertible.'
. I've checked and this is happend because I use IAnimal
in BindableProprety. I just want to create custom control with generic type and use it in another ContentPage
, is it even possible?
Your BindableProperty
can probably be reduce to either IEnumerable<object>
or IEnumerable<IAnimal
:
public static readonly BindableProperty AnimalsProperty =
BindableProperty.Create(nameof(AnimalsProperty), typeof(IEnumerable<IAnimal>), typeof(Overview), null);
public IEnumerable<IAnimal> Animals
{
get { return (IEnumerable<IAnimal>)GetValue(AnimalsProperty); }
set { SetValue(AnimalsProperty, value); }
}
I would probably add INotifyPropertyChanged
to your IAnimal
interface:
public interface IAnimal : INotifyPropertyChanged
{
}
As to the implementation of Dogs
, there's no need for CommunityToolkit.Mvvm
. This is because ObservableCollections are assigned once and it's their CollectionChanged events is what we're after, i.e.
public partial class DogViewModel: ObservableObject
{
public ObservableCollection<Dog> Dogs { get; } = new ();
}