Xamarin forms tabbed page not retrieving data from in OnAppearing - xamarin.forms

I retrieve data from the Azure database to show one of the tabbed pages. when calling the method from ViewModel in OnAppearing not retrieve data, but when click the button it retrieves and shows on the page.
Please advice If I have constructed ViewModel and view correctly? if so why it doesn't work. ?
Connection manager:
public partial class DatabaseManager
{
static DatabaseManager defaultInstance = new DatabaseManager();
MobileServiceClient client;
IMobileServiceTable<Person> personTable;
private DatabaseManager()
{
this.client = new MobileServiceClient(Constants.AzureMobileAppURL);
this.personTable = client.GetTable<Person>();
}
public static DatabaseManager DefaultManager
{
get
{
return defaultInstance;
}
private set
{
defaultInstance = value;
}
}
public MobileServiceClient CurrentClient
{
get { return client; }
}
}
Model:
public class Person
{
[JsonProperty(PropertyName = "FirstName")]
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
[JsonProperty(PropertyName = "DisplayName")]
public string DisplayName
{
get { return displayName; }
set { displayName = value; }
}
[JsonProperty(PropertyName = "LastName")]
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
}
ViewModel:
public class ProfilePageViewModel : ViewModelBase
{
DatabaseManager manager;
string firstName = "";
string lastName = "";
string displayName = "";;
IMobileServiceTable<Person> personTable;
public ProfilePageViewModel()
{
manager = DatabaseManager.DefaultManager;
this.personTable = manager.CurrentClient.GetTable<Person>();
RefreshCommand = new Command(
execute: async () =>
{
try
{
await GetProfileAsync();
}
catch
{
}
});
}
public async Task GetProfileAsync()
{
try
{
IEnumerable<Person> items = await personTable
.Where(pserson => pserson.Active)
.ToEnumerableAsync();
foreach (var item in items)
{
FirstName = item.FirstName;
LastName = item.LastName;
DisplayName = item.DisplayName;
}
}
catch (Exception e)
{
}
}
public string FirstName
{
private set { SetProperty(ref firstName, value); }
get { return firstName; }
}
public string LastName
{
private set { SetProperty(ref lastName, value); }
get { return lastName; }
}
public string DisplayName
{
private set { SetProperty(ref displayName, value); }
get { return displayName; }
}
public ICommand RefreshCommand { private set; get; }
}
View:
ProfilePage.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"
x:Class="SLSNZ.Views.ProfilePage"
xmlns:controls="clr-
namespace:ImageCircle.Forms.Plugin.Abstractions;
assembly=ImageCircle.Forms.Plugin"
xmlns:local="clr-namespace:SLSNZ.ViewModels"
Title="Profile">
<ContentPage.Resources>
<ResourceDictionary>
<local:ProfilePageViewModel x:Key="viewModel">
</local:ProfilePageViewModel>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Icon>
<OnPlatform x:TypeArguments="FileImageSource">
<On Platform="iOS" Value="icon-profile.png" />
</OnPlatform>
</ContentPage.Icon>
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="0, 20, 0, 0" />
</ContentPage.Padding>
<StackLayout BindingContext="{StaticResource viewModel}">
<Label Text="Display Name"
TextColor="Gray"
FontSize="Small"
HorizontalOptions="Start" />
<Label Text="{Binding DisplayName}"
VerticalOptions="Center"
HorizontalOptions="Start"
VerticalOptions="Start/>
<Label Text="First Name"
TextColor="Gray"
FontSize="Small"
HorizontalOptions="Start" />
<Label Text="{Binding FirstName}"
FontSize="Large"
HorizontalOptions="Start"
VerticalOptions="Start" />
<Label Text="Last Name"
TextColor="Gray"
FontSize="Small"
HorizontalOptions="Start" />
<Label Text="{Binding LastName}"
FontSize="Large"
HorizontalOptions="Start"
VerticalOptions="Start" />
<Button Text="Refresh"
Command="{Binding RefreshCommand}"
Grid.Row="0" Grid.Column="1"/>
</StackLayout>
</ContentPage>
View:
ProfilePage.cs
public partial class ProfilePage : ContentPage
{
ProfilePageViewModel viewModel;
public ProfilePage()
{
InitializeComponent();
viewModel = new ProfilePageViewModel();
}
protected override async void OnAppearing()
{
base.OnAppearing();
await viewModel.GetProfileAsync();
}
}
ViewModelBase:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value,
[CallerMemberName] string propertyName =
null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName
= null)
{
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(propertyName));
}
}

In your view by the time you await viewModel.GetProfileAsync(); The view will already render.
Your GetProfileAsync in the View Model does an await so will get the data then update it.
I suggest changing the IMobileServiceTable personTable to a property and implement a on Property change to notify the view that the data has changes.
So your viewmodel should implement INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
Then when the Data Changes you can notify it in the view model like:
OnPropertyChanged("personTable");
Also in your view change your code to:
pre-initialize the viewmodel:
public ProfilePage()
{
InitializeComponent();
SetViewModel();
}
protected async void SetViewModel()
{
viewmodel = await viewModel.GetProfileAsync();
}
This way you wont block the UI thread and when you call the OnPropertyChnage it will notify your view to update.
UPDATE:
I have created a small sample Xamarin project for you to demonstrate how you can bind and notify the view of changes.
You had a few issues in your view as well where your DisplayName label was not closed properly and you had duplicate properties for HorizontalOptions in some labels.
Download this Xamarin sample. It had hard coded data but will show you the flow of setting the data and the Binding Context of the View without locking the UI thread.
https://github.com/loanburger/54430503

Related

Saving a list with SQL

I have an Entry, A save button and a list view. when a user add an entry to this list how can I save this with SQL so next time I come back to the app, the List is not resets. I have create a Model and a view model for this Job.
public class Energys
{
public int Id { get; set; }
public string EE {get; set;}
}
and view model
class Viewmodel
{
public ICommand AddEnergyCommand => new Command(AddEnergy);
public IList<Energys> energy { get; set; }
public Viewmodel()
{
try
{
energy = new ObservableCollection<Energys>();
energy.Add(new Energys { Id = 1, EE = "6 MV" });
energy.Add(new Energys { Id = 2, EE = "10 MV" });
}
catch (Exception ex)
{
}
}
public void AddEnergy()
{
energy.Add(new Energys { Id = 3, EE = "15 MV" });
}
}
I know working with Sql is not simple but ....
so how can I save all energys by AddEnergycomamnd for all time.
From Store data in a local SQLite.NET database, if you want to insert data in sqlite database, you need to install sqlite-net-pcl by nuget package.
Then creating model, the ID property is marked with PrimaryKey and AutoIncrement attributes to ensure that each Energys instance in the SQLite.NET database will have a unique id provided by SQLite.NET.
public class Energys
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string EE { get; set; }
}
Finally, you need to connect sqlite database, and create table.
public partial class Page4 : ContentPage
{
public SQLiteConnection conn;
public ICommand AddEnergyCommand => new Command(AddEnergy);
public ICommand CreateEnergyCommand => new Command(CreateTable);
private ObservableCollection<Energys> _energy;
public ObservableCollection<Energys> energy
{
get { return _energy; }
set
{
_energy = value;
OnPropertyChanged("energy");
}
}
public Page4()
{
InitializeComponent();
conn = GetSQLiteConnection();
CreateTable();
energy = new ObservableCollection<Energys>(conn.Table<Energys>().ToList());
this.BindingContext = this;
}
public SQLiteConnection GetSQLiteConnection()
{
var fileName = "Energys.db";
var documentPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
var path = Path.Combine(documentPath, fileName);
var connection = new SQLiteConnection(path);
return connection;
}
private void AddEnergy()
{
Energys e = new Energys();
e.EE = entry1.Text;
var data = conn.Table<Energys>();
var result = conn.Insert(e);
if (result > 0)
{
Console.WriteLine("Sucessfully Added");
}
else
{
Console.WriteLine("Already energy id Exist");
}
energy = new ObservableCollection<Energys>(conn.Table<Energys>().ToList());
entry1.Text = "";
}
private void CreateTable()
{
conn.CreateTable<Energys>();
}
}
<StackLayout>
<Entry x:Name="entry1" />
<StackLayout Orientation="Horizontal">
<Button
x:Name="btncreate"
Command="{Binding CreateEnergyCommand}"
Text="create table" />
<Button
x:Name="btnsave"
Command="{Binding AddEnergyCommand}"
Text="save data" />
</StackLayout>
<ListView HasUnevenRows="True" ItemsSource="{Binding energy}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding EE}" />
<Label Text="{Binding Id}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
Update:
About delete item from sqlite database, you can get ListView selected item, then delete this item from sqlite database.
private Energys _selecteditem;
public Energys selecteditem
{
get { return _selecteditem; }
set
{
_selecteditem = value;
OnPropertyChanged("selecteditem");
}
}
<ListView
HasUnevenRows="True"
ItemsSource="{Binding energy}"
SelectedItem="{Binding selecteditem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding EE}" />
<Label Text="{Binding Id}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
public ICommand DeleteEnergyCommand => new Command(DeleteEnergy);
private void DeleteEnergy()
{
if(selecteditem!=null)
{
conn.Delete(selecteditem);
}
energy = new ObservableCollection<Energys>(conn.Table<Energys>().ToList());
}

Xamarin Forms: How can i correctly bind data from two view models to a single view?

This is the short code for testing purpose. The problem is that the UI is not displaying the Text from the Label which is binded with ViewModelB. In debugging when I hover the mouse in xaml over the Text from the Label I see the right binding data is there, but the UI simply won't display. With ViewModelA there are no problems.
In XAML:
<StackLayout>
<StackLayout>
<StackLayout.BindingContext>
<testbinding:ViewModelA/>
</StackLayout.BindingContext>
<Button Command ="{Binding Get}"/>
</StackLayout>
<StackLayout>
<StackLayout.BindingContext>
<testbinding:ViewModelB/>
</StackLayout.BindingContext>
<Label Text="{Binding Metadata}"/>
</StackLayout>
ViewModelA: where BaseViewModel is a INotifyPropertyChanged interface
public ViewModelA:BaseViewModel
{
public ViewModelA()
{
Get = new Command(SendText);
vmB = new ViewModelB();
}
ViewModelB vmB;
public ICommand Get { get; }
private void SendText()
{
string data = "someText";
vmB.GetMetadata(data);
}
}
ViewModelB is like this:
class ViewModelB:BaseViewModel
{
private string _metadata = string.Empty;
public string Metadata
{
get { return _metadata; }
set
{
_metadata = value;
OnPropertyChanged();
}
}
GetMetadata()
{
Metadata = "Some text";
}
}
In ViewModelA there are more properties which I need and in ViewModelB is just one property which gets data from a function. I could make just one ViewModel from both of them which works fine, but I'm trying to keep them smaller and organized. I already tried so many scenarios and is getting really frustrating.
Thanks for helping.
In the second StackLayout in your xaml file you're not binding it's BindingContext property to the ViewModelB instance from ViewModelA but instead you are creating a new one.
Here's a working solution for you:
public class ViewModelA : BaseViewModel
{
public ViewModelB ViewModelB { get; }
public ICommand GetMetadataCommand { get; }
public ViewModelA()
{
ViewModelB = new ViewModelB();
GetMetadataCommand = new Command((_) => GetMetadata());
}
private void GetMetadata()
{
string data = "someText";
ViewModelB.GetMetadata(data);
}
}
public class ViewModelB : BaseViewModel
{
private string _metadata;
public string Metadata
{
get { return _metadata; }
set
{
_metadata = value;
OnPropertyChanged();
}
}
public void GetMetadata(string data)
{
Metadata = data;
}
}
XAMl:
<StackLayout>
<StackLayout x:Name="StackLayout1">
<StackLayout.BindingContext>
<local:ViewModelA />
</StackLayout.BindingContext>
<Button Command ="{Binding GetMetadataCommand}"/>
</StackLayout>
<StackLayout BindingContext="{Binding Source={x:Reference StackLayout1}, Path=BindingContext.ViewModelB}">
<Label Text="{Binding Metadata}" />
</StackLayout>
</StackLayout>

How a user select to display 1 out of two (or more) fields on a single Label in Xamarin

I'm trying to use a single Label to display one of the two data fields alternately in Xamarin Forms. Only Label 1 Displaying the binding field (Contact_Name), while second Label which I am trying to use a variable "DisplayField" is not displaying either 'Contact_Address' or 'Contact_eMail' .
Question posted before and Another user tried to help but it didn't work!
Model Class
public class Contacts
{
[PrimaryKey][Autoincrement]
public int Contact_ID { get; set; }
public string Contact_Name { get; set; }
public string Contact_Address { get; set; }
public string Contact_eMail { get; set; }
}
XAML Page
<StackLayout>
<Button Text="Display Address" FontSize="Large" HorizontalOptions="Center" VerticalOptions="Fill" Clicked="Display_Address" />
<Button Text="Display Email" FontSize="Large" HorizontalOptions="Center" VerticalOptions="Fill" Clicked="Display_eMail" />
<Entry HorizontalOptions="FillAndExpand" Text="{Binding DisplayField}" />
<ListView x:Name="listView" HasUnevenRows="True" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<StackLayout Orientation="Vertical" VerticalOptions="CenterAndExpand" >
<Frame >
<StackLayout Orientation="Vertical" VerticalOptions="Center">
<Label Text="{Binding Contact_Name}" FontSize="Medium" LineBreakMode="WordWrap" />
<Label Text="{Binding DisplayField}" LineBreakMode="WordWrap" />
</StackLayout>
</Frame>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
Code Behind
public partial class FieldSwap : ContentPage
{
readonly FieldViewModel _fieldViewModel;
readonly SQLiteAsyncConnection _connection = DependencyService.Get<ISQLite>().GetConnection();
public ObservableCollection<Contacts> CList { get; set; }
public static string DisplayField { get; private set; }
public static int caseSwitch { get; private set; }
public FieldSwap()
{
InitializeComponent();
_fieldViewModel = new FieldViewModel();
_fieldViewModel.Field = "Contact_Address";
this.BindingContext = _fieldViewModel;
}
public static void SelectField()
{
switch (caseSwitch)
{
case 1:
DisplayField = "Contact_Address";
break;
case 2:
DisplayField = "Contact_eMail";
break;
default:
DisplayField = ("Contact_Address");
break;
}
}
private void Display_Address(object sender, EventArgs e)
{
caseSwitch = 1;
SelectField();
ReadData();
}
private void Display_eMail(object sender, EventArgs e)
{
caseSwitch = 2;
SelectField();
ReadData();
}
public void ReadData()
{
var list = _connection.Table<Contacts>().ToListAsync().Result;
CList = new ObservableCollection<Contacts>(list);
listView.ItemsSource = CList;
}
}
View Model Class
public class FieldViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
String _field;
public string Field
{
set
{
if (!value.Equals(_field, StringComparison.Ordinal))
{
_field = value;
OnPropertyChanged("DisplayField");
}
}
get
{
return _field;
}
}
void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(propertyName));
}
}
You could use IsVisible property to achieve that, not need to bind only one lable.
Therefore, binding Contact_Address and Contact_eMail with two lables in StackLayout as follows:
<StackLayout Orientation="Vertical" VerticalOptions="Center">
<Label Text="{Binding Contact_Name}" FontSize="Medium" LineBreakMode="WordWrap" />
<Label Text="{Binding Contact_Address}" IsVisible="{Binding AddressVisible}" LineBreakMode="WordWrap" />
<Label Text="{Binding Contact_eMail}" IsVisible="{Binding EMailVisible}" LineBreakMode="WordWrap" />
</StackLayout>
Then in Contacts add two visiable proerty:
public class Contacts: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
...
private bool addressVisible;
public bool AddressVisible
{
set
{
if (addressVisible != value)
{
addressVisible = value;
OnPropertyChanged("AddressVisible");
}
}
get
{
return addressVisible;
}
}
private bool eMailVisible;
public bool EMailVisible
{
set
{
if (eMailVisible != value)
{
eMailVisible = value;
OnPropertyChanged("EMailVisible");
}
}
get
{
return eMailVisible;
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Now in Contentpage, you could modify the visiable propery when button be clicked:
private void Display_Address(object sender, EventArgs e)
{
foreach(var item in CList )
{
item.AddressVisible = true;
item.EMailVisible = false;
}
}
private void Display_eMail(object sender, EventArgs e)
{
foreach (var item in CList )
{
item.AddressVisible = false;
item.EMailVisible = true;
}
}
Here is the effect:

Showing Empty Screen in FlowListView in Xaml Xamarin.Forms

How to do FlowListView in XAML Xamarin.Forms?
Here is my Code:
XAML:
<flv:FlowListView FlowColumnCount="3" SeparatorVisibility="None" HasUnevenRows="true" x:Name="grid_list" ItemsSource="{Binding list_grid}" HeightRequest="100" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Image Source="{Binding Image}" Margin="20" VerticalOptions="Fill" HorizontalOptions="Fill" XAlign="Center" YAlign="Center"/>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
CODE.cs
public partial class PlanCampaign_DetailPage : ContentPage
{
ObservableCollection<CarosualImages> list_grid { get; set; }
public PlanCampaign_DetailPage()
{
InitializeComponent();
this.BindingContext = this;
list_grid = new ObservableCollection<CarosualImages>()
{
new CarosualImages { Image="maharastra.jpg"},
new CarosualImages {Image="delhi.jpg"},
new CarosualImages {Image="delhi.jpg"},
new CarosualImages {Image="delhi.jpg"},
new CarosualImages {Image="delhi.jpg"},
};
grid_list.ItemsSource = list_grid;
}
ModelClass:
public class CarosualImages
{
public string Image { get; set; }
}
Could anyone tell that where i did mistake here, this is showing Empty Screen.
Here is the code for INotifyPropertyChanged
public class CarosualImages : INotifyPropertyChanged
{
private string _name = String.Empty;
public CarosualImages()
{
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string ImageName
{
get { return _name; }
set
{
_name= value;
OnPropertyChanged();
}
}
}
Put Public before
ObservableCollection<CarosualImages> list_grid { get; set; }

Xamarin ListView Grouping results in blackscreen

I'm developing an app with Xamarin.Forms (xaml), but now i have a strange behavior with the grouping of the ListView
I have a ListView with a CustomCell if i display it without grouping everything works as expected, but if I set IsGroupingEnabled to true the screen is getting black.
Before Grouping:
With grouping
I have no idea what i'm missing or what i did wrong.
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:cell="clr-namespace:BrindaApp.Cells"
x:Class="BrindaApp.Tabs.MainTab" Title="Main">
<StackLayout>
<StackLayout Orientation="Horizontal">
<Entry Placeholder="Search" HorizontalOptions="StartAndExpand"></Entry>
<Image x:Name="image_Group" HorizontalOptions="End">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="Group_Tapped" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
<StackLayout VerticalOptions="FillAndExpand">
<ListView ItemsSource="{Binding ProductSource}" HasUnevenRows="True" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" x:Name="mainListView"
RelativeLayout.HeightConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=1,Constant=0}" IsPullToRefreshEnabled="True" BackgroundColor="Black"
GroupDisplayBinding="{Binding Category}" GroupShortNameBinding="{Binding Category}" IsGroupingEnabled="True">
<ListView.Resources>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<cell:ProductCell ImageUrl="{Binding ProductImageUrl}" Difficult="{Binding Difficult}" Titel="{Binding Titel}" IsFavorit="{Binding IsFavorit}" ProductId="{Binding ProductId}"
RelativeLayout.HeightConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.2,Constant=0}" Height="200" Tapped="ProductCell_Tapped"
></cell:ProductCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--</RelativeLayout>-->
</StackLayout>
</StackLayout>
<!--<Label Text="Some Text"/>-->
</ContentPage>
MainPage.xaml.cs
public partial class MainTab : ContentPage
{
ProductsViewModel viewModel;
public bool IsGrouped { get; set; }
public MainTab()
{
viewModel = new ProductsViewModel();
BindingContext = viewModel;
InitializeComponent();
viewModel.mainListView = mainListView;
image_Group.Source = ImageSource.FromResource("BrindaApp.Imgs.group.png");
}
private void ProductCell_Tapped(object sender, EventArgs e)
{
Navigation.PushAsync(new ProductDetails());
}
private void Group_Tapped(object sender, EventArgs e)
{
if(IsGrouped)
{
mainListView.IsGroupingEnabled = false;
}
else
{
mainListView.IsGroupingEnabled = true;
}
IsGrouped = !IsGrouped;
}
}
Model:
public class ProductModel
{
public string ProductImageUrl { get; set; }
public string Titel { get; set; }
public int Difficult { get; set; }
public bool IsFavorit { get; set; }
public string ProductId { get; set; }
public string Category { get; set; }
}
ViewModel
public class ProductsViewModel:BaseViewModel
{
public ListView mainListView;
ObservableCollection<ProductModel> productSource;
public ObservableCollection<ProductModel> ProductSource
{
get
{
return productSource;
}
set
{
productSource = value;
FirePropertyChanged("ProductSource");
}
}
public ICommand RefreshListView { get; set; }
public ProductsViewModel()
{
ProductSource = new ObservableCollection<ProductModel>();
ProductSource.Add(new ProductModel() { ProductImageUrl = "https://media-cdn.tripadvisor.com/media/photo-s/02/d7/5a/1c/essen-trinken.jpg", IsFavorit = true, Category = "Test" });
ProductSource.Add(new ProductModel() { ProductImageUrl = "https://www.burgerking.at/003_at/website/slider/17_028_pop_cheesemas16_at/17_028_pop_cheesemas16_at_startseitenslider_01_product_angusclaus.png", Category = "Test" });
ProductSource.Add(new ProductModel() { ProductImageUrl = "https://media-cdn.tripadvisor.com/media/photo-s/02/d7/5a/1c/essen-trinken.jpg", IsFavorit = true });
ProductSource.Add(new ProductModel() { ProductImageUrl = "https://www.burgerking.at/003_at/website/slider/17_028_pop_cheesemas16_at/17_028_pop_cheesemas16_at_startseitenslider_01_product_angusclaus.png", Category = "Test" });
FirePropertyChanged("ProductSource");
RefreshListView = new Command(() =>
{
//TODO refresh list
mainListView.IsRefreshing = false;
},
() =>
{
return true;
});
}
}
I'm struggeling here for days and cannot find an answer, hopefuly someone can help me.
As guid i used: https://developer.xamarin.com/guides/xamarin-forms/user-interface/listview/customizing-list-appearance/#Grouping
When reading the link you also referred to yourself, you are required to create a list of lists:
Create a list of lists (a list of groups, each group being a list of elements).
Right now, you just have a flat list which is most likely why you experience your issue.
An example, also taken from the same link, is as follows:
static PageTypeGroup()
{
List<PageTypeGroup> Groups = new List<PageTypeGroup> {
new PageTypeGroup ("Alfa", "A"){
new PageModel("Amelia", "Cedar", new switchCellPage(),""),
new PageModel("Alfie", "Spruce", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Ava", "Pine", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Archie", "Maple", new switchCellPage(), "grapefruit.jpg")
},
new PageTypeGroup ("Bravo", "B"){
new PageModel("Brooke", "Lumia", new switchCellPage(),""),
new PageModel("Bobby", "Xperia", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Bella", "Desire", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Ben", "Chocolate", new switchCellPage(), "grapefruit.jpg")
}
}
All = Groups; //set the publicly accessible list
}

Resources