Xamarin Forms Binding Context and Bindings
I think in BuildTabs you want something more like:
FuturePage.BindingContext = RootPage.Future;
Instead of
FuturePage.SetBinding(ListView.ItemsSourceProperty, "Future");
Since your "FuturePage" is not a ListView but a ContentPage and you are setting a BindingContext not assigning a binding.
![Chad Bonthuys](https://i.stack.imgur.com/pU34C.jpg?s=256&g=1)
Chad Bonthuys
Senior C# developer for DPO|Paygate in the Fintech space
Updated on June 04, 2022Comments
-
Chad Bonthuys about 2 years
What Im Trying to Achieve:
I have a Xamarin forms application that retrieves data via an API call, this data is set to the GamesResultModel and bound to a public property in the .APP, the data is then displayed in a listview. Now I have got it working when using multiple pages each binding to the data they require however I only want to use one page that is instantiated multiple times and the binding source and page title is set when instantiated.
Problem:
Im not sure how I can set the binding source of a page when the page is instantiated from the rootpage? I tried the below but it did not work
public static GamesPageModel Future { get; set; } FuturePage.SetBinding(ListView.ItemsSourceProperty, "Future");
Code Example:
public class RootPage : TabbedPage { public static GamesPageModel History { get; set; } public static GamesPageModel Current { get; set; } public static GamesPageModel Future { get; set; } public RootPage() { ShowLoginDialog(); buildTabs(); }
From the rootpage I instantiate a new instance of the GamesPage for each timespan:
private void buildTabs() { var historyPage = new GamesPage(); historyPage.Title = "History"; historyPage.SetBinding(ListView.ItemsSourceProperty, "History"); var todayPage = new GamesPage(); todayPage.Title = "Current"; todayPage.SetBinding(ListView.ItemsSourceProperty, "Today"); var FuturePage = new GamesPage(); FuturePage.Title = "Future"; FuturePage.SetBinding(ListView.ItemsSourceProperty, "Future"); this.Children.Add(todayPage); this.Children.Add(historyPage); this.Children.Add(futurePage); }
Games Result Model where the API Call is set:
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] public partial class GamesResult { [System.Xml.Serialization.XmlArrayItemAttribute("item", IsNullable = false)] public xmlItem[] previous { get; set; } [System.Xml.Serialization.XmlArrayItemAttribute("item", IsNullable = false)] public xmlItem[] current { get; set; } [System.Xml.Serialization.XmlArrayItemAttribute("item", IsNullable = false)] public xmlItem[] future { get; set; } } [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] public partial class xmlItem { public ushort field_id { get; set; } public string field_desc { get; set; } public ushort fk_round_id { get; set; } public string field_start_time { get; set; } public byte tee_interval { get; set; } public byte fk_course_id { get; set; } public uint field_pin { get; set; } public ushort fourball_id { get; set; } public ushort fk_field_id { get; set; } public ushort fk_course_hole_id_tee_off { get; set; } public string tee_off_time { get; set; } public ushort fourball_team_id { get; set; } public byte team_desc { get; set; } public ushort fk_fourball_id { get; set; } public ushort fourball_player_id { get; set; } public ushort fk_player_mem_id { get; set; } public byte player_hc { get; set; } public ushort fk_player_team { get; set; } public byte fk_player_tee { get; set; } public ushort round_id { get; set; } public string round_desc { get; set; } public ushort fk_tour_id { get; set; } public string round_date { get; set; } public ushort tour_id { get; set; } public string tour_desc { get; set; } public xmlItemTour_start tour_start { get; set; } public xmlItemTour_end tour_end { get; set; } public ushort fk_member_id { get; set; } public xmlItemCreate_date create_date { get; set; } public byte fk_comp_typ_id { get; set; } public byte tour_status { get; set; } }
Games Page:
public class GamesPage : ContentPage { #region Private Properties private GamesPageModel viewModel { get { return BindingContext as GamesPageModel; } } private ListView listView; #endregion this.Content = new StackLayout() { Children ={ listView } }; } public GamesPage() { this.SetBinding(TitleProperty, "Title"); listView = new ListView(); var viewTemplate = new DataTemplate(typeof(GameViewCell)); listView.ItemTemplate = viewTemplate; listView.SetBinding(ListView.ItemsSourceProperty, "Games");
Games Page Model:
public class GamesPageModel { public GamesPageModel() { Games = new List<xmlItem>(); } public string Title { get; set; } public List<xmlItem> Games { get; set; } }
Game View Cell:
public class GameViewCell : ViewCell { public GameViewCell() { Label tour_Desc = new Label() { Font = Font.BoldSystemFontOfSize(15) }; Label round_Desc = new Label(); Label field_Desc = new Label(); tour_Desc.SetBinding(Label.TextProperty, "tour_desc"); round_Desc.SetBinding(Label.TextProperty, "round_desc"); field_Desc.SetBinding(Label.TextProperty, "field_desc"); var layout = new StackLayout(); layout.Children.Add(tour_Desc); layout.Children.Add(round_Desc); layout.Children.Add(field_Desc); this.View = layout; } }
Singleton used to set the data on return of the API call to be utilised anywhere in the application:
public class App { private static readonly App instance = new App(); private LoginResult loginResult; private GamesResult gamesResult; public static App Instance { get { return instance; } } public LoginResult LoginResult { get { return loginResult; } set { loginResult = value; } } public GamesResult GamesResult { get { return gamesResult; } set { gamesResult = value; } } }
With a simple implementation with multiple pages this is working as seen by the below example:
var todayPage = new CurrentGamesPage(); var historyPage = new HistoryGamesPage(); var futurePage = new FutureGamesPage(); this.Children.Add(todayPage); this.Children.Add(historyPage); this.Children.Add(futurePage); public class HistoryGamesPage : ContentPage { private ListView listView; public HistoryGamesPage() { Title = "Current Games"; listView = new ListView(); BindData(); this.Content = new StackLayout() { Children = { listView } }; } public void BindData() { if (App.Instance.GamesResult != null) { try { var viewTemplate = new DataTemplate(typeof(GameViewCell)); listView.ItemTemplate = viewTemplate; listView.ItemsSource = App.Instance.GamesResult.previous; } catch(Exception ex) { Debug.WriteLine(ex.Message); } } } }