Reputation: 1439
I've followed a number of examples from the formal Xamarin doco on XAML data binding as well as a PluralSight tutorial which illustrates defining custom ViewCells in C# code and having issues. Firstly I'd rather use XAML due to its fluidity but I'm having major issues. This example is the most recent one that seems to make clear sense to me but something's missing as my datasource never binds if I specify ItemsSource in the XAML. Here's my 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:TOFApp"
x:Class="MyApp.MainPage"
Title="MyApp"
Padding="0,20,0,0">
<StackLayout>
<!-- Place new controls here -->
<ListView x:Name="thingyList"
ItemsSource="{Binding ThingyList}"
CachingStrategy="RecycleElement"
SelectedItem="{Binding SelectedThingy}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Padding="15,5,5,5">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="OnThingyTapped"></TapGestureRecognizer>
</StackLayout.GestureRecognizers>
<Image Source="" HeightRequest="50" WidthRequest="50" />
<StackLayout Orientation="Vertical">
<Label Text="{Binding Name}"
VerticalOptions="Center"
HorizontalOptions="StartAndExpand"
FontSize="Medium" />
<Label Text="{Binding Description}"
VerticalOptions="Center"
HorizontalOptions="StartAndExpand"
FontSize="Micro"
FontAttributes="Italic" />
<Label Text=""
IsVisible="false" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
and the code behind
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
ThingyList = new ObservableCollection<Thingy>
{
new Thingy {Id = 1, Name = "First Thingy", Description = "Kinda fun mate!"},
new Thingy {Id = 2, Name = "Second Thingy", Description = "Not as fun"},
new Thingy {Id = 3, Name = "Third Thingy", Description = "Downright awful"}
};
Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0);
/////this.thingyList.ItemsSource = ThingyList;
}
private Thingy _selectedThingy;
public Thingy SelectedThingy
{
get { return _selectedThingy; }
set
{
if (_selectedThingy != value)
{
_selectedThingy = value;
}
}
}
public ObservableCollection<Thingy> ThingyList { get; set; }
private void OnThingyTapped(object sender, EventArgs e)
{
}
}
public class Thingy
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
So as is I will see an empty ListView so the binding is failing (I'm sure I've done everything in the video link), but if I uncomment the c# line (from the coded tutorial on PluralSight) to assign the instanced public property then it does work and I'll see items in my list...BUT tapping an item (changing the selected item) never invokes the SelectedThingy setter (I've put breakpoints in and they're never reached). I've tried it with and without the tapped handler defined. What I need is to be able to reach the underlying SelectedItem where I'll access some properties for further processing.
I'm using Xamarin as installed with Visual Studio 2017 Community Edition in a Cross platform app with a shared project for the common UI code.
Anyone know what I'm doing wrong?
Upvotes: 0
Views: 215
Reputation: 9144
Add BindingContext in in either XAML
<ContentPage.BindingContext>
<local:MyViewModel/>
</ContentPage.BindingContext>
or Codebehind
this.BindingContext = new MyViewModel();
Good practice is to create a ViewModel class for a XAML page and initialize it like above, add all your Thingy
properties in ViewModel in that case to retain MVVM structure.
Upvotes: 1
Reputation: 89214
you need to specify a BindingContext
public MainPage()
{
InitializeComponent();
this.BindingContext = this;
Upvotes: 6