I'm building a custom view using an ObservableCollection as a BindableProperty (my goal was to update the format of the view depending its contents, in this case a list of colors). I think I have the property set up properly in the custom view. If I set the bindable property in C#, it works. If I try to use a {Binding varname} inside XAML, it throws a "Specified Cast is not Valid" error. I'm trying to figure out where my issue is.
Below in public MainPage() you can see the commented out line where I manually set the property. If I uncomment this and take "Color={Binding Test}" out of MainPage.xaml, everything works. If I run this as is, I get the exception.
Here is all my code:
MainPage.xaml.cs
public partial class MainPage : ContentPage
{
public ObservableCollection<Color> Test { get; set; }
public MainPage()
{
Test = new ObservableCollection<Color>();
Test.Add(Color.Blue);
Test.Add(Color.Green);
Test.Add(Color.Red);
Test.Add(Color.Purple);
this.BindingContext = this;
InitializeComponent();
//myView.Colors = Test;
}
private void OnClicked(object sender, EventArgs e)
{
myView.Colors.Add(Color.Yellow);
}
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ColorBoxes"
x:Class="ColorBoxes.MainPage">
<StackLayout HorizontalOptions="CenterAndExpand">
<local:ColorBoxView x:Name="myView" Colors="{Binding Test}" WidthRequest="400" HeightRequest="600"/>
<Button Text="Add Color" Clicked="OnClicked"/>
</StackLayout>
</ContentPage>
ColorBoxView.xaml.cs
public partial class ColorBoxView : ContentView
{
public ColorBoxView()
{
InitializeComponent();
}
public static BindableProperty ColorList = BindableProperty.Create(
propertyName: "Colors",
returnType: typeof(ObservableCollection<Color>),
declaringType: typeof(ColorBoxView),
defaultValue: new ObservableCollection<Color>(),
defaultBindingMode: BindingMode.OneWay,
propertyChanged: HandleColorListPropertyChanged
);
public ObservableCollection<Color> Colors
{
get { return (ObservableCollection<Color>) base.GetValue(ColorList); }
set
{
if (value != this.Colors)
{
base.SetValue(ColorList, value);
Colors.CollectionChanged += Items_CollectionChanged;
}
}
}
void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
buildView(Colors);
}
private void buildView(ObservableCollection<Color> newColors)
{
/* This code is never reached */
}
private static void HandleColorListPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
ObservableCollection<Color> newColors = (ObservableCollection<Color>) newValue;
ColorBoxView thisView = (ColorBoxView) bindable;
thisView.buildView(newColors);
}
ColorBoxView.xaml
<?xml version="1.0" encoding="utf-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ColorBoxes.ColorBoxView" >
<Grid x:Name="BoxGrid" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
RowSpacing="0" ColumnSpacing="0" Padding="0">
</Grid>
</ContentView>
Stack Trace:
System.InvalidCastException: Specified cast is not valid.
at ColorBoxes.MainPage.InitializeComponent () [0x00023] in /Users/docmani/RiderProjects/ColorBoxes/ColorBoxes/ColorBoxes/obj/Debug/netstandard2.0/MainPage.xaml.g.cs:26
at ColorBoxes.MainPage..ctor () [0x00060] in /Users/docmani/RiderProjects/ColorBoxes/ColorBoxes/ColorBoxes/MainPage.xaml.cs:25
at ColorBoxes.App..ctor () [0x0000f] in /Users/docmani/RiderProjects/ColorBoxes/ColorBoxes/ColorBoxes/App.xaml.cs:15
at ColorBoxes.iOS.AppDelegate.FinishedLaunching (UIKit.UIApplication app, Foundation.NSDictionary options) [0x00007] in /Users/docmani/RiderProjects/ColorBoxes/ColorBoxes/ColorBoxes.iOS/AppDelegate.cs:25
at at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.18.2.1/src/Xamarin.iOS/UIKit/UIApplication.cs:86
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0000e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.18.2.1/src/Xamarin.iOS/UIKit/UIApplication.cs:65
at ColorBoxes.iOS.Application.Main (System.String[] args) [0x00001] in /Users/docmani/RiderProjects/ColorBoxes/ColorBoxes/ColorBoxes.iOS/Main.cs:16
Additional Info - I tried upgrading Xamarin.Forms in NuGet since it had been a while. Now it won't even compile with the binding. It gives me:
MainPage.xaml(9, 46): [XFC0009] No property, BindableProperty, or event found for "Colors", or mismatching type between value and property.
But again, if I manually set the value in C# it still works. I'm definitely missing something in my XAML but I don't know what it is.