Missing list view details when refreshing - c#

I have a list that list all of my customers. I refresh the list when I typed something in my search box. My problem is when I type something the list became unstable meaning the details for example the customer name is missing in some parts of the list.
I will show you what I mean.
This what the list looked like upon loading:
Image :
This is what the list looked like when I tapped the item (I refreshed the list when I tapped an item) or search something:
Now here is my code to list the page.
Here is my XAML Code:
<ListView SeparatorVisibility="Default" x:Name="lstActivity" ItemSelected="LstActivity_ItemSelected" ItemTapped="LstActivity_ItemTapped" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame StyleClass="lstframe" CornerRadius="0" BorderColor="Transparent" HasShadow="False">
<StackLayout StyleClass="lstContainer" VerticalOptions="CenterAndExpand">
<Grid>
<Label VerticalTextAlignment="Center" StyleClass="lstActivityName" VerticalOptions="Center" Grid.Row="0" Grid.Column="0" Text="{Binding ActivityDescription}">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="SFProDisplay-Regular.ttf#SFProDisplay-Regular"/>
</OnPlatform>
</Label.FontFamily>
</Label>
<Switch VerticalOptions="Center" Grid.Row="0" Grid.Column="1" IsEnabled="False" IsToggled="{Binding Selected}" />
</Grid>
</StackLayout>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is my XAML.cs Code:
public void List_Activity()
{
try
{
var keyword = entSearchActivity.Text;
if (String.IsNullOrEmpty(keyword))
{
var query = DefaultSettings.conn.QueryAsync<ActivityTable>("SELECT ActivityDescription, ActivityID, Selected FROM tblActivity ORDER BY ActivityDescription LIMIT 20");
var resultCount = query.Result.Count;
if (resultCount > 0)
{
lstActivity.IsVisible = true;
result = query.Result;
lstActivity.ItemsSource = result;
}
else
{
lstActivity.IsVisible = false;
}
}
else
{
var query = DefaultSettings.conn.QueryAsync<ActivityTable>("SELECT ActivityDescription, ActivityID, Selected FROM tblActivity WHERE ActivityDescription LIKE '%" + keyword +"%' ORDER BY ActivityDescription LIMIT 20");
var resultCount = query.Result.Count;
if (resultCount > 0)
{
lstActivity.IsVisible = true;
result = query.Result;
lstActivity.ItemsSource = result;
}
else
{
lstActivity.IsVisible = false;
}
}
}
catch (Exception ex)
{
Crashes.TrackError(ex);
}
}
And here is my ActivityTable.cs:
[Table("tblActivity")]
public class ActivityTable
{
[PrimaryKey]
public string ActivityID { get; set; }
public string ActivityDescription { get; set; }
public string RecordLog { get; set; }
public DateTime LastSync { get; set; }
public DateTime LastUpdated { get; set; }
public int Deleted { get; set; }
public int Checked { get; set; }
public int Finished { get; set; }
public bool Selected { get; set; }
}
My questions are:
What is/are the cause(s) of this?
How can I avoid this in the future?

Related

ListView ItemSource ObservableRangeCollection<> accessing Model ObservableRangeCollection<>

I'm developing an .NET Xamarin App. I want to list all Products as ItemTemplate in the Grouped-ListView and Invoice.Name as Header. Currently I only get the GroupHeaderTemplate shown in my Grouped-ListView.
Model: Invoice.cs
public class Invoice : ObservableRangeCollection<Invoice>
{
public string Name { get; set; }
public Company Company { get; set; }
public ObservableRangeCollection<Product> Products { get; set; }
}
Model: Products.cs
public class Product : ObservableRangeCollection<Product>
{
public string Name { get; set; }
public DateTime ExpireDate { get; set; }
}
ViewModel: MainViewVM (creating fake data)
public ObservableRangeCollection<Invoice> Invoices { get; set; }
public MainViewVM()
{
Invoices.Add(new Invoice { Name = "Test1", Company = new Company { Image = image }, Products = new ObservableRangeCollection<Product>() { new Product { Name = "ProductTest1", CreatedDate = DateTime.Now }, new Product { Name = "ProductTest2", CreatedDate = DateTime.Now } } });
Invoices.Add(new Invoice { Name = "Test2", Company = new Company { Image = image }, Products = new ObservableRangeCollection<Product>() { new Product { Name = "ProductTest3", CreatedDate = DateTime.Now }, new Product { Name = "ProductTest4", CreatedDate = DateTime.Now } } });
}
View: MainViewVM (ListView)
<ListView
IsGroupingEnabled="True"
ItemsSource="{Binding Invoices}">
<ListView.GroupHeaderTemplate>
<DataTemplate x:DataType="models:Invoice">
<ViewCell>
<StackLayout Orientation="Horizontal" VerticalOptions="Center" HorizontalOptions="Center">
<Image Source="{Binding Company.Image}" WidthRequest="66" VerticalOptions="Center"/>
<Label Text="{Binding Name}" VerticalOptions="Center"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:Product">
<ViewCell>
<StackLayout VerticalOptions="Center">
<Label Text="{Binding Name}" VerticalOptions="Center"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
I added a constructor with : base. That fixed it for me.
https://learn.microsoft.com/de-de/xamarin/xamarin-forms/user-interface/collectionview/grouping
public Invoice(string name, Company company, ObservableRangeCollection<Product> products) : base(products)
{
Name = name;
Company = company;
Products = products;
}

xamarin forms dependent dropdown using local json data and multiple item selection

in my xamarin forms application registration part i need to fill profession and expertise field from a local json.The profession field is a dropdown and then expertise is also a dropdown and subpart of profession.From expertise field i need to select minimum one and maximum 3 options.
ProfessionalRegistrationPage.xaml.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ProfessionalRegistrationPage : ContentPage
{
public List<Profession> professions { get; set; }
public List<Profession> expertises { get; set; }
public ProfessionalRegistrationPage()
{
InitializeComponent();
professions = GetJsonDataProfession();
BindingContext = this;
professionPicker.ItemsSource = professions;
professionPicker.SelectedItem = professions[0];
}
private List<Profession> GetJsonDataProfession()
{
string jsonFileName = "profession.json";
ProfessionList ObjProfessionList = new ProfessionList();
var assembly = typeof(MainPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{ assembly.GetName().Name}.{ jsonFileName}");
using (var reader = new StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
ObjProfessionList = JsonConvert.DeserializeObject<ProfessionList>(jsonString);
}
return ObjProfessionList.professions;
}
private void professionPicker_SelectedIndexChanged(object sender, EventArgs e)
{
Picker picker = (Picker)sender;
int selectedIndex = picker.SelectedIndex;
if (selectedIndex != -1)
{
expertises = professions[selectedIndex].expertises;
expertisePicker.ItemsSource = expertises;
expertisePicker.SelectedItem = expertises[0];
}
}
}
public partial class ProfessionList
{
[JsonProperty("professions")]
public List<Profession> professions { get; set; }
}
public partial class Profession
{
[JsonProperty("expertises")]
public List<Profession> expertises { get; set; }
[JsonProperty("professionname")]
public string ProfessionName { get; set; }
[JsonProperty("expertisename")]
public string ExpertiseName { get; set; }
}
ProfessionalRegistrationPage.xaml
<StackLayout Orientation="Vertical">
<Label Text="Profession"
TextColor="{StaticResource BackgroundGradientStart}">
</Label>
<Frame BackgroundColor="Transparent"
BorderColor="{StaticResource BackgroundGradientStart}"
Padding="0"
Margin="10"
CornerRadius="15"
HorizontalOptions="FillAndExpand">
<Picker
x:Name="professionPicker"
SelectedIndexChanged="professionPicker_SelectedIndexChanged"
ItemDisplayBinding="{Binding ProfessionName}"
ItemsSource="{Binding profession}"
TextColor="{StaticResource White}"/>
</Frame>
</StackLayout>
<StackLayout Orientation="Vertical">
<Label Text="Expertise"
TextColor="{StaticResource BackgroundGradientStart}">
</Label>
<Frame
BackgroundColor="Transparent"
BorderColor="{StaticResource BackgroundGradientStart}"
Padding="0"
Margin="10"
CornerRadius="15"
HorizontalOptions="FillAndExpand">
<Picker x:Name="expertisePicker"
ItemDisplayBinding="{Binding ExpertiseName}"
ItemsSource="{Binding profession}"
TextColor="{StaticResource White}"/>
</Frame>
</StackLayout>
profession.json
{
"professions": [
{
"professionname": "Doctor",
"expertises": [
{
"expertisename": "Pediatric"
},
{
"expertisename": "Ortho"
}
]
},
{
"professionname": "Engineer",
"expertises": [
{
"expertisename": "Software"
},
{
"expertisename": "Civil"
}
]
}
]
}
i used picker here.but picker doesnot support more than one item selection.
otherwise its works perfectly.
i think i need to place a popup and in pop up page i need to fix a listview and checkbox. but i dont now how to do that. I am new to xamarin.

Grouped Collection View list not displaying, possible Binding error

I just began working with the MVVM layout and I cannot seem to display anything in my collectionView List. I believe it's my binding, unfortunately I don't really understand how I am supposed to bind a grouped list + the ViewModel. I read to bind to the path no the source, but I'm pretty sure I am doing this incorrectly. I have checked to see if I am even getting shares to load and I am, they're just not displaying.
Model -- Share
[JsonProperty("iSpottedID")]
public int ID { get; set; }
[JsonProperty("sShoppingList")]
[MaxLength(255)]
public string ShoppingName { get; set; }
[JsonProperty("dtInfoUpdate")]
[MaxLength(20)]
public string CreateDate { get; set; }
[JsonProperty("iProductID")]
public int ProductID { get; set; }
[Indexed]
[JsonProperty("sLocation")]
[MaxLength(255)]
public string LocationName { get; set; }
[JsonProperty("tvCardJson")]
public string JsonString { get; set; }
ViewModel -- SharesViewModel
public class SharesViewModel : BaseViewModel
{
#region Properties
private int _id;
public int ID
{
get { return _id; }
set
{
SetValue(ref _id, value);
OnPropertyChanged(nameof(ID));
}
}
private string _longName;
public string LongName
{
get { return _longName; }
set
{
SetValue(ref _longName, value);
OnPropertyChanged(nameof(LongName));
}
}
private string _date;
public string CreateDate
{
get{ return _date;}
set
{
SetValue(ref _date, value);
OnPropertyChanged(nameof(CreateDate));
}
}
private int _prodID;
public int ProductID
{
get { return _id; }
set
{
SetValue(ref _prodID, value);
OnPropertyChanged(nameof(ProductID));
}
}
private string _json;
public string JsonString
{
get { return _json; }
set
{
SetValue(ref _json, value);
OnPropertyChanged(nameof(JsonString));
}
}
private string _location;
public string LocationName
{
get { return _location; }
set
{
SetValue(ref _location, value);
OnPropertyChanged(nameof(LocationName));
}
}
//ADD-ONS
public string Address
{
get
{
if (!string.IsNullOrEmpty(JsonString))
{
var jsonDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(JsonString);
if (jsonDict.ContainsKey("address"))
if (jsonDict["address"] != "")
return jsonDict["address"];
}
return null;
}
}
private ImageSource _imageLink;
public ImageSource ImageLink
{
get
{
if(ProductID != 0)
{
...
return ImageSource.FromUri(link);
}
return null;
}
}
#endregion
public SharesViewModel(){}
public SharesViewModel(Share share)
{
ID = share.ID;
ProductID = share.ProductID;
JsonString = share.JsonString;
CreateDate = share.CreateDate;
LocationName = share.LocationName;
}
List View Model -- SharesListViewlModel
public class SharesListViewModel : BaseViewModel
{
private SharesViewModel _selectedShare;
private bool _isDataLoaded;
//grouped list
public ObservableCollection<LocationSpotGroups<string, SharesViewModel>> Shares { get; set; }
...
public ICommand OpenMoreSharesCommand { get; private set; }
public ICommand LoadDataCommand { get; private set; }
public SharesListViewModel(Position NW , Position SE)
{
_nw = NW;
_se = SE;
LoadDataCommand = new Command(async () => await LoadData());
OpenMoreSharesCommand = new Command<SharesViewModel>(async (share) => await OpenMoreShares(share));
public ObservableCollection<SharesViewModel> sList { get; set; }
= new ObservableCollection<SharesViewModel>();
}
private async Task LoadData()
{
if (_isDataLoaded)
return;
var list = await _connection.GetAllRegionShares(_nw, _se);
foreach (var spot in list)
{
sList.Add(new SharesViewModel(spot));
}
var sorted = from item in sList
orderby item.LocationName
group item by item.LocationName into itemGroup
select new LocationSpotGroups<string, SharesViewModel>(itemGroup.Key, itemGroup);
Shares = new ObservableCollection<LocationSpotGroups<string, SharesViewModel>>(sorted);
}
LocationSpotGroups
public class LocationSpotGroups<K, T> : ObservableCollection<T>
{
public K GroupKey { get; set; }
public IEnumerable<T> GroupedItem { get; set; }
public LocationSpotGroups(K key, IEnumerable<T> shares)
{
GroupKey = key;
GroupedItem = shares;
foreach (var item in shares)
{
this.Items.Add(item);
}
}
}
SharesPage XAML
<CollectionView x:Name="CollectionList"
VerticalOptions="FillAndExpand"
ItemsSource="{Binding Shares}"
IsGrouped="True">
<!--HEADER-->
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal"
Padding="5"
BackgroundColor="#f7f7fb">
<Label x:Name="labelname"
Text="{Binding GroupKey}"
HorizontalOptions="Start"
VerticalOptions="Center"
TextColor="gray" />
</StackLayout>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>
<!--BODY-->
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="5" Margin="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ImageButton Source="{Binding ImageLink}"
WidthRequest="150"
HeightRequest="150"
Grid.ColumnSpan="2"
CornerRadius="15"
Aspect="AspectFill"
Grid.Row="0"
Grid.Column="0"/>
<Label Text="{Binding ShoppingName}"
Grid.Row="1"
Grid.Column="0"/>
<Label Text="More"
Grid.Row="1"
Grid.Column="1"
HorizontalTextAlignment="End"/>
<Label Text="{Binding CreateDate}"
Grid.Row="2"
Grid.Column="0"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
SharesPage CS
public SharesPage( Position NW, Position SE )
{
InitializeComponent();
ViewModel = new SharesListViewModel(NW, SE);
}
public SharesListViewModel ViewModel
{
get { return BindingContext as SharesListViewModel; }
set { BindingContext = value; }
}
protected override void OnAppearing()
{
ViewModel.LoadDataCommand.Execute(null);
base.OnAppearing();
}
Loading the data in the constructor works if the data is not a lot, which is wasn't in my case. Everything loads perfectly.

Xamarin - Grouping List Views

I've got some issues with grouping my List Views.
When I isgroupingenabled = "true" my List only shows the groupDisplayBinding name.
I've read and tried so many things and wasn't able to apply them to my project I need your help now.
I've seen I need to put an Observablecollection but don't know where and how to do it.
My Model
public class League
{
public string name { get; set; }
public string country { get; set; }
public string logo { get; set; }
public string flag { get; set; }
}
public class HomeTeam
{
public int team_id { get; set; }
public string team_name { get; set; }
public string logo { get; set; }
}
public class AwayTeam
{
public int team_id { get; set; }
public string team_name { get; set; }
public string logo { get; set; }
}
public class Score
{
public string halftime { get; set; }
public string fulltime { get; set; }
public string extratime { get; set; }
public string penalty { get; set; }
}
public class Fixture
{
public int fixture_id { get; set; }
public int league_id { get; set; }
public League league { get; set; }
public DateTime event_date { get; set; }
public int event_timestamp { get; set; }
public int? firstHalfStart { get; set; }
public int? secondHalfStart { get; set; }
public string round { get; set; }
public string status { get; set; }
public string statusShort { get; set; }
public int elapsed { get; set; }
public string venue { get; set; }
public string referee { get; set; }
public HomeTeam homeTeam { get; set; }
public AwayTeam awayTeam { get; set; }
public int? goalsHomeTeam { get; set; }
public int? goalsAwayTeam { get; set; }
public Score score { get; set; }
}
public class Api
{
public int results { get; set; }
public List<Fixture> Fixtures { get; set; }
}
public class RootFixtures
{
public Api api { get; set; }
}
My JSON : (Part of it)
{"api": {
"results": 162,
"fixtures": [
{
"fixture_id": 234670,
"league_id": 900,
"league": {
"name": "Division 1",
"country": "Saudi-Arabia",
"logo": null,
"flag": "https://media.api-sports.io/flags/sa.svg"
},
"event_date": "2020-03-10T00:00:00+00:00",
"event_timestamp": 1583798400,
"firstHalfStart": null,
"secondHalfStart": null,
"round": "Regular Season - 28",
"status": "Match Postponed",
"statusShort": "PST",
"elapsed": 0,
"venue": "Prince Saud bin Jalawi Stadium (al-Khobar (Khobar))",
"referee": null,
"homeTeam": {
"team_id": 2933,
"team_name": "Al-Qadisiyah FC",
"logo": "https://media.api-sports.io/teams/2933.png"
},
"awayTeam": {
"team_id": 2928,
"team_name": "Al Khaleej Saihat",
"logo": "https://media.api-sports.io/teams/2928.png"
},
"goalsHomeTeam": null,
"goalsAwayTeam": null,
"score": {
"halftime": null,
"fulltime": null,
"extratime": null,
"penalty": null
}
}
]
}
}
ListMatchPage :
public partial class ListMatchs : ContentPage
{
string JsonLeagues = "The Json Below"
public ListMatchs()
{
InitializeComponent();
var Leagues = JsonConvert.DeserializeObject<RootFixtures>(JsonLeagues);
LeaguesList.ItemsSource = Leagues.api.Fixtures;
}
}
I'm new at dev and here I Hope my english wasn't too bad.
edit :
MyXAML :
<ContentPage.Content>
<StackLayout>
<Label Text="Futurs matchs" HorizontalTextAlignment="Center" />
<ListView x:Name="LeaguesList" GroupDisplayBinding="{Binding Path=League.name}"
GroupShortNameBinding="{Binding Path=League.name}"
IsGroupingEnabled="True" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Height="30">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Aspect="AspectFit" Source="{Binding Path=homeTeam.logo}" />
<Label Grid.Column="1" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="Center" TextColor="Black" FontSize="15" FontAttributes="Bold" Text="{Binding Path=homeTeam.team_name}" HorizontalOptions="CenterAndExpand"/>
<Label Grid.Column="2" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="Center" TextColor="Black" FontSize="15" FontAttributes="Bold" Text="{Binding Path=awayTeam.team_name}" HorizontalOptions="CenterAndExpand"/>
<Image Grid.Column="3" Aspect="AspectFit" Source="{Binding Path=awayTeam.logo}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
#JackHUA here is what I did :
XAML.CS :
ObservableCollection<groupedfix> FixturesCollection = new ObservableCollection<groupedfix>();
public ListMatchs()
{
InitializeComponent();
var Leagues = JsonConvert.DeserializeObject<RootFixtures>(JsonLeagues);
foreach (var match in Leagues.api.Fixtures)
{
int fixtureid = match.fixture_id;
DateTime fixturedate = match.event_date;
int FixtureLeagueid = match.league_id;
string FixtureLeague = match.league.name;
string FixtureLeaguelogo = match.league.logo;
string Hometeamname = match.homeTeam.team_name;
string Hometeamlogo = match.homeTeam.logo;
string Awayteamname = match.awayTeam.team_name;
string Awayteamlogo = match.awayTeam.logo;
HomeTeam HOMETEAM = new HomeTeam() { team_name = Hometeamname, logo = Hometeamlogo };
AwayTeam AWAYTEAM = new AwayTeam() { team_name = Awayteamname, logo = Awayteamlogo };
League LEAGUE = new League() { logo = FixtureLeaguelogo, name = FixtureLeague };
Fixture MATCH = new Fixture() { fixture_id = fixtureid, event_date = fixturedate, league_id = FixtureLeagueid, league = LEAGUE, homeTeam = HOMETEAM, awayTeam = AWAYTEAM };
groupedfix GROUPEDFIX = new groupedfix(FixtureLeague) { MATCH };
FixturesCollection.Add(GROUPEDFIX);
}
LeaguesList.ItemsSource = FixturesCollection;
}
public class groupedfix : List<Fixture>
{
public string FixtureLeague { get; set; }
public groupedfix(string Name )
{
FixtureLeague = Name;
}
}
XAML :
<ContentPage.Content>
<StackLayout>
<Label Text="Futurs matchs" HorizontalTextAlignment="Center" />
<ListView x:Name="LeaguesList" GroupDisplayBinding="{Binding FixtureLeague}"
IsGroupingEnabled="True" HasUnevenRows="True" ItemTapped="Newgameclick">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Height="30">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Aspect="AspectFit" Source="{Binding Path=homeTeam.logo}"/>
<Label Grid.Column="1" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="Center" TextColor="Black" FontSize="15" FontAttributes="Bold" Text="{Binding Path=homeTeam.team_name}" HorizontalOptions="CenterAndExpand"/>
<Label Grid.Column="2" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="Center" TextColor="Black" FontSize="15" FontAttributes="Bold" Text="{Binding Path=awayTeam.team_name}" HorizontalOptions="CenterAndExpand"/>
<Image Grid.Column="3" Aspect="AspectFit" Source="{Binding Path=awayTeam.logo}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
The image result :
See the pic
But when I change
LeaguesList.ItemsSource = FixturesCollection;
in
LeaguesList.ItemsSource = FixturesCollection.GroupBy(F => F.FixtureLeague);
I get this : See the pic
With error :
[0:] Binding:'FixtureLeague' property not found on 'System.Linq.Grouping`2[System.String,BeastTIPS.Pages.ListMatchs+groupedfix]'...
[0:] Binding: 'homeTeam' property not found on 'BeastTIPS.Pages.ListMatchs+groupedfix'...
[0:] Binding: 'awayTeam' property not found on 'BeastTIPS.Pages.ListMatchs+groupedfix'...
The List is groupedby but my Binding are not found
I can't find what property to Bind.
The model you added to the ItemsSource should in a right format as the document mentioned, I wrote a example for you and you can check the code:
public partial class MainPage : ContentPage
{
ObservableCollection<myModel> FixtureCollection = new ObservableCollection<myModel>();
public MainPage()
{
InitializeComponent();
League LeagueOne = new League() { name = "one" };
League LeagueTwo = new League() { name = "two" };
League LeagueThree = new League() { name = "three" };
HomeTeam HomeTeamOne = new HomeTeam() { team_name = "HomeTeamOne" };
HomeTeam HomeTeamTwo = new HomeTeam() { team_name = "HomeTeamTwo" };
HomeTeam HomeTeamThree = new HomeTeam() { team_name = "HomeTeamThree" };
AwayTeam AwayTeamOne = new AwayTeam() { team_name = "AwayTeamOne" };
AwayTeam AwayTeamTwo = new AwayTeam() { team_name = "AwayTeamTwo" };
AwayTeam AwayTeamThree = new AwayTeam() { team_name = "AwayTeamThree" };
Fixture FixtureOne = new Fixture() { league = LeagueOne, homeTeam = HomeTeamOne, awayTeam = AwayTeamOne};
Fixture FixtureTwo = new Fixture() { league = LeagueTwo, homeTeam = HomeTeamTwo, awayTeam = AwayTeamTwo };
Fixture FixtureThree = new Fixture() { league = LeagueThree, homeTeam = HomeTeamThree, awayTeam = AwayTeamThree };
myModel myModelOne = new myModel(FixtureOne.league.name) { FixtureOne };
myModel myModelTwo = new myModel(FixtureTwo.league.name) { FixtureTwo };
myModel myModelThree = new myModel(FixtureThree.league.name) {FixtureThree };
FixtureCollection.Add(myModelOne);
FixtureCollection.Add(myModelTwo);
FixtureCollection.Add(myModelThree);
LeaguesList.ItemsSource = FixtureCollection;
BindingContext = this;
}
}
public class myModel : List<Fixture>
{
public string name { get; set; }
public myModel( string Name) {
name = Name;
}
}
And in code behind:
<StackLayout>
<Label Text="Futurs matchs" HorizontalTextAlignment="Center" />
<ListView x:Name="LeaguesList"
GroupDisplayBinding="{Binding name}"
GroupShortNameBinding="{Binding name}"
IsGroupingEnabled="True" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Height="30">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Aspect="AspectFit" Source="{Binding Path=homeTeam.logo}" />
<Label Grid.Column="1" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="Center" TextColor="Black" FontSize="15" FontAttributes="Bold" Text="{Binding Path=homeTeam.team_name}" HorizontalOptions="CenterAndExpand"/>
<Label Grid.Column="2" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="Center" TextColor="Black" FontSize="15" FontAttributes="Bold" Text="{Binding Path=awayTeam.team_name}" HorizontalOptions="CenterAndExpand"/>
<Image Grid.Column="3" Aspect="AspectFit" Source="{Binding Path=awayTeam.logo}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
I also uploaded my sample project here and feel free to ask me any question.
Update:
I think what you really need is OrderBy not GroupBy:
LeaguesList.ItemsSource = FixturesCollection.OrderBy(f => f.FixtureLeague).ToList();
When you use GroupBy, you can set a breakpoint right there to check the LeaguesList.ItemsSource, you will find the structure has been change, the count of LeaguesList.ItemsSource becomes 56.
There is another problem in your xaml, the GroupDisplayBinding should bind to FixtureLeague not name:
<ListView x:Name="LeaguesList" GroupDisplayBinding="{Binding FixtureLeague}"

Max rows listview xamarin

I have a list view that displays a ladder of points on a sports team and am trying to only show the top 5 players. Is there anyway that this can be in XAML?
Thanks,
Ryan
EDIT: Here is my code
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="MIApp.PlayerPage">
<ContentPage.Content>
<StackLayout Margin="20,0,0,0" Orientation="Vertical" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
<Label Text="Player Info" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
<Grid MinimumHeightRequest="200" RowSpacing="10" Padding="0">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition/>
<RowDefinition Height="50"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Text="Goal Leaders" Grid.Row="0" Margin="0"/>
<ListView x:Name="GoalListView" Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" Margin="0,0,0,0" Spacing="0" VerticalOptions="Center">
<Label Text="{Binding StrFullName}" HorizontalOptions="Start" VerticalTextAlignment="Center"/>
<Label Text="{Binding IntGoals}" HorizontalOptions="End" VerticalTextAlignment="Center"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Label Text="Point Leaders" Grid.Row="2" Margin="0"/>
<ListView x:Name="PointListView" HasUnevenRows="true" Grid.Row="3" Margin="0,0,0,0">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" Margin="0,0,0,0" Spacing="0" VerticalOptions="Center">
<Label Text="{Binding StrFullName}" HorizontalOptions="Start" VerticalTextAlignment="Center"/>
<Label Text="{Binding IntPoints}" HorizontalOptions="End" VerticalTextAlignment="Center"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Code Behind:
public partial class PlayerPage : ContentPage
{
public PlayerPage()
{
InitializeComponent();
}
protected async override void OnAppearing()
{
base.OnAppearing();
HttpClient client = new HttpClient();
string urlGoals = "https://melbourneicewebapi.azurewebsites.net/api/Player_Info/GetPlayer_Info?playerInfo=goals";
string urlPoints = "https://melbourneicewebapi.azurewebsites.net/api/Player_Info/GetPlayer_Info?playerInfo=points";
var responseGoals = await client.GetAsync(urlGoals);
var responsePoints = await client.GetAsync(urlPoints);
if (responsePoints.IsSuccessStatusCode)
{
string resGoals = "";
using (HttpContent contentGoals = responseGoals.Content)
{
Task<string> resultGoals = contentGoals.ReadAsStringAsync();
resGoals = resultGoals.Result;
var GoalsList = Players.PlayersItems.FromJson(resGoals);
GoalListView.ItemsSource = GoalsList;
}
string resPoints = "";
using (HttpContent contentPoints = responsePoints.Content)
{
Task<string> resultPoints = contentPoints.ReadAsStringAsync();
resPoints = resultPoints.Result;
var PointsList = Players.PlayersItems.FromJson(resPoints);
PointListView.ItemsSource = PointsList;
}
}
else
{
await DisplayAlert("Connection Error", "Please Connect to the internet and try again", "Ok");
}
}
}
Players Class where objects are created from JSON string and added into a list:
public class Players
{
public partial class PlayersItems
{
[JsonProperty("$id")]
public long Id { get; set; }
[JsonProperty("intPlayerID")]
public int IntPlayerId { get; set; }
[JsonProperty("strFirstName")]
public string StrFirstName { get; set; }
[JsonProperty("strSurname")]
public string StrSurname { get; set; }
[JsonProperty("intGamesPlayed")]
public int IntGamesPlayed { get; set; }
[JsonProperty("strPosition")]
public string StrPosition { get; set; }
[JsonProperty("intPlayerNumber")]
public int IntPlayerNumber { get; set; }
[JsonProperty("intGoals")]
public int IntGoals { get; set; }
[JsonProperty("intAssists")]
public int IntAssists { get; set; }
[JsonProperty("intPoints")]
public int IntPoints { get; set; }
public string StrFullName {
get
{
return StrFirstName.Trim() + " " + StrSurname.Trim();
}
}
}
public partial class PlayersItems
{
public static List<PlayersItems> FromJson(string json)
{
return JsonConvert.DeserializeObject<List<PlayersItems>>(json);
}
}
}
So what I am essentially doing is accessing an API that gives me two JSON Strings of all the data entries in the Players Table,One that is sorted by highest points, the other by highest goals, it is then converted into a list of objects from the Players Class, and then set to the appropriate List View.
use LINQ to select the top X scores before assigning them to ItemsSource. I'm not aware of any way to filter the data directly in XAML
var PointsList = Players.PlayersItems.FromJson(resPoints);
var topPoints = PointsList.OrderByDescending(x => x.PointsInt).Take(5).ToList();
PointListView.ItemsSource = topPoints;

Categories