Reputation: 1642
I have got a custom Page and a custom Control.
public class TilesPage : ContentPage
{
public ObservableCollection<Tile> Tiles
{
get;
set;
}
}
public class Tile : Frame
{
public static readonly BindableProperty TitleProperty = BindableProperty.Create(nameof(Title), typeof(string), typeof(Tile), null);
public Tile()
{
HasShadow = false;
}
public string Title
{
get
{
return (string)GetValue(TitleProperty);
}
set
{
SetValue(TitleProperty, value);
}
}
}
So my page has a Collection of Tiles, that are Frames. Now I want to populate the Collection via XAML.
My XAML Sytax is like this:
<?xml version="1.0" encoding="utf-8" ?>
<CPages:TilesPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyNamespace.AboutPage"
xmlns:CControls="clr-namespace:MyNamespace;assembly=MyAssembly"
xmlns:CPages="clr-namespace:MyNamespace;assembly=MyAssembly"
>
<CPages:TilesPage.Tiles>
<CControls:Tile Title="Test">
<CControls:Tile.Content>
<Label>In Tile</Label>
</CControls:Tile.Content>
</CControls:Tile>
</CPages:TilesPage.Tiles>
</CPages:TilesPage>
But the Collection stays empty. The XAML does not touch it.
So what is wrong with my Syntax?
Upvotes: 0
Views: 355
Reputation: 13601
There are two issues I see in the code:
We need a default constructor that calls InitializeComponent()
public TilesPage()
{
InitializeComponent();
}
XAML parser expects a not-null collection at this point - so that it can add multiple elements. Else it will throw a parse-exception for either type-mismatch, or null value. To fix that, we need to ensure there is a default value to work with.
public ObservableCollection<Tile> _tiles = new ObservableCollection<Tile>();
public ObservableCollection<Tile> Tiles {
get { return _tiles; }
set { _tiles = value; }
}
You should now be able to see the updated collection:
protected override void OnAppearing()
{
base.OnAppearing();
Debug.WriteLine(Tiles?.Count);
foreach (var tile in Tiles)
Debug.WriteLine(tile.Title);
}
Also, would recommend converting this property to bindable - for easier integration with XAML framework (not mandatory).
public static readonly BindableProperty TilesProperty =
BindableProperty.Create(nameof(Tiles), typeof(IList<Tile>), typeof(TilesPage),
defaultValue: new ObservableCollection<Tile>());
public IList<Tile> Tiles
{
get
{
return (IList<Tile>)GetValue(TilesProperty);
}
set
{
SetValue(TilesProperty, value);
}
}
Upvotes: 1