Hello,
I have a problem with ListView and MVVM pattern. This is my environment:
- Windows 8.1 Pro (x64)
- Visual Studio Enterprise 2015 Update 3
- Xamarin 4.2.2.6
- Xamarin.Forms 2.3.3.180
- MvvmLight 5.3.0
I started new Blank Xaml App (Xamarin.Forms Portable) and then I uncheck Windows Phone Silverlight 8.1 from portable library targets.
This is my model, RssSchema.cs
(nothing special, only some properties):
namespace Rss.Model
{
public class RssSchema
{
public string Id { get; set; }
public string Title { get; set; }
public string Summary { get; set; }
public string Content { get; set; }
public string ImageUrl { get; set; }
public string ExtraImageUrl { get; set; }
public string MediaUrl { get; set; }
public string FeedUrl { get; set; }
public string Author { get; set; }
public DateTime PublishDate { get; set; }
}
}
My view model, FeedViewModel.cs
with FeedTitle
and Items
properties. To test, in the constructor I fill Items
property with 3 RssSchema
objects:
namespace Rss.ViewModel
{
public class FeedViewModel : ViewModelBase
{
private ObservableCollection<RssSchema> items = null;
public ObservableCollection<RssSchema> Items
{
get { return this.items; }
set
{
if (this.items == value) { return; }
this.items = value;
this.RaisePropertyChanged(nameof(this.Items));
}
}
private string feedTitle = string.Empty;
public string FeedTitle
{
get { return this.feedTitle; }
set
{
if (this.feedTitle == value) { return; }
this.feedTitle = value;
this.RaisePropertyChanged(nameof(this.FeedTitle));
}
}
public FeedViewModel()
{
List<RssSchema> list = new List<RssSchema>();
for (int i = 0; i < 3; i++)
{
RssSchema item = new RssSchema();
item.Title = $"Title {i}";
list.Add(item);
}
this.Items = new ObservableCollection<RssSchema>(list);
this.FeedTitle = "My blog feed";
}
}
}
As I'm using MVVM Light I have a ViewModelLocator.cs
(nothing special, only Feed
property):
namespace Rss.ViewModel
{
public class ViewModelLocator
{
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<FeedViewModel>();
}
public FeedViewModel Feed
{
get
{
return ServiceLocator.Current.GetInstance<FeedViewModel>();
}
}
public static void Cleanup() { }
}
}
And I create an instace of it in App.xaml
:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Rss.App"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d1p1:Ignorable="d"
xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:d4p1="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="clr-namespace:Rss.ViewModel" />
</ResourceDictionary>
</Application.Resources>
</Application>
Finally, this is my view, FeedPage.xaml
with one Label
and one ListView
:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Rss.Pages.FeedPage"
BindingContext="{Binding Source={StaticResource Locator}, Path=Feed}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Text="{Binding FeedTitle}" HorizontalOptions="Center"/>
<ScrollView Grid.Row="1" Padding="10">
<ListView ItemsSource="{Binding Items}" VerticalOptions="Start">
<!--<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Label Text="{Binding Title}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>-->
</ListView>
</ScrollView>
</Grid>
</ContentPage>
The Label
shows the feed title, so the BindingContext
is properly set. As you can see I have the ListView.ItemTemplate
in comments. In this way when I run the app I see the 3 items with the default ToString()
value (the class complete name):
Rss.Model.RssSchema
Rss.Model.RssSchema
Rss.Model.RssSchema
You can imagine that I don't want to see this content, but if I uncomment the ListView.ItemTemplate
part and run the app I get this exception in runtime:
Unhandled Exception:
System.InvalidCastException: Specified cast is not valid.
Do you know what is happening?