ListView not triggering ItemTapped - xaml

I've been working on a school assignment, where you need to load data into a ListView. According to the course manual, you need to use 'ObservableCollection' which I figured out. However, I can't seem to get the ItemTapped to work.
I'm creating the following table using SQLite.
public class Settings
{
[Primarykey]
public string Name { get; set; }
[MaxLength(255)]
public string Value { get; set; }
}
Then on the OnAppearing I initialise the database and add a row of data.
public partial class SQL : ContentPage
{
private SQLiteAsyncConnection _connection;
private ObservableCollection<Settings> _settings;
public SQL()
{
InitializeComponent();
_connection = DependencyService.Get<ISQLiteDb>().GetConnection();
}
protected override async void OnAppearing()
{
await _connection.CreateTableAsync<Settings>();
var settings_name = new Settings { Name = "Meaning of Life", Value = "42" };
await _connection.InsertAsync(settings_name);
await DisplayAlert("Alert", "Value Added to database!", "OK");
var settings = await _connection.Table<Settings>().ToListAsync();
_settings = new ObservableCollection<Settings>(settings);
ListView.ItemsSource = _settings;
base.OnAppearing();
}
void MyItemTapped (object sender, System.EventArgs e)
{
DisplayAlert("Alert", "You Pressed Something!", "OK");
}
void MyItemSelected (object sender, System.EventArgs e)
{
DisplayAlert("Alert", "You Selected Something!", "OK");
}
}
In my XAML file, I have the following, with the ItemTapped going to the function above.
<?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="BudgetBuddy.SQL">
<ContentPage.Content>
<ListView x:Name="ListView">
<ListView.ItemTemplate ItemTapped="MyItemTapped" ItemSelected="MyItemSelected">
<DataTemplate>
<TextCell Text="{Binding Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
I can't figure out what I'm doing wrong. Why doesn't my ItemTapped and ItemSelected work? Also, what would be the best way to access the Value associated with the Name I pressed in the ListView from the ObservableCollection

The reason your ItemTapped and ItemSelected aren't working is because they are in the wrong location.
This is what you have:
<?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="BudgetBuddy.SQL">
<ContentPage.Content>
<ListView x:Name="ListView">
<ListView.ItemTemplate ItemTapped="MyItemTapped" ItemSelected="MyItemSelected">
<DataTemplate>
<TextCell Text="{Binding Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
This is what you should do:
<?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="BudgetBuddy.SQL">
<ContentPage.Content>
<ListView x:Name="ListView" ItemTapped="MyItemTapped" ItemSelected="MyItemSelected">
<ListView.ItemTemplate >
<DataTemplate>
<TextCell Text="{Binding Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>

Related

How to display a list of class objects in a Collection View?

I want to display a list (observable collection) of BleDevice type in my view. I'm using mvvm pattern in .net maui (.net 7).
Model:
public class BleDevice
{
public BleDevice(){}
public BleDevice(string name, string mac)
{
Name = name;
MacAddress = mac;
}
public string Name { get; set; }
public string MacAddress { get; set; }
}
ViewModel:
public partial class MainViewModel: ObservableObject
{
public MainViewModel()
{
devices = new ObservableCollection<BleDevice>();
devices.Add(new BleDevice("Mystronics Winder", "00:00:00:00:00"));
devices.Add(new BleDevice("Living Room TV", "25:e7:aa:05:84"));
}
[ObservableProperty]
ObservableCollection<BleDevice> devices;
}
View(xaml): (Edited)
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp2.MainPage"
xmlns:viewmodel="clr-namespace:MauiApp2.ViewModel"
xmlns:model="clr-namespace:MauiApp2.Model"
x:DataType="viewmodel:MainViewModel">
<VerticalStackLayout>
<CollectionView ItemsSource="{Binding Devices}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{model:BleDevice}">
<Grid>
<Label Text="{Binding Name}"/>
<Label Text="{Binding MacAddress}"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ContentPage>
Error:
XFC0045 Binding: Property "Name" not found on "MauiApp2.ViewModel.MainViewModel". MauiApp2 \source\repos\MauiApp2\MauiApp2\View\MainPage.xaml
Why it does recognize the "{Binding Devices}" but not "{Binding Name}" and "{Binding MacAddress}"?
ViewModel Remove the [ObservableProperty] attribute and change to this:
public partial class MainViewModel : ObservableObject
{
public MainViewModel()
{
Devices = new ObservableCollection<BleDevice>();
Devices.Add(new BleDevice("Mystronics Winder", "00:00:00:00:00"));
Devices.Add(new BleDevice("Living Room TV", "25:e7:aa:05:84"));
}
public ObservableCollection<BleDevice> Devices { get; set; }
}
View(xaml) Remove the x:DataType="xxx":
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp2.MainPage"
xmlns:viewmodel="clr-namespace:MauiApp2.ViewModel"
xmlns:model="clr-namespace:MauiApp2.Model"
>
<VerticalStackLayout>
<CollectionView ItemsSource="{Binding Devices}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Name}"/>
<Label Text="{Binding MacAddress}"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ContentPage>

Code Behind Xamarin forms launch a function in another page

I have 2 ContentView in MyWordPage.Xaml which are MyWordListView and AddWordsView
My MyWordPage.Xaml looks like this :
<ContentView x:Name="MyWordListView" >
<CollectionView x:Name="ListOfWords" IsVisible="False"
SelectionMode="Single" >
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout >
<Label Text="{Binding .}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentView>
<ContentView IsVisible="False" x:Name="AddWordsView" />
<pv:PancakeView HorizontalOptions="End" VerticalOptions="End" Margin="0,0,10,150" Padding="10" CornerRadius="10">
<Image HeightRequest="30" WidthRequest="30" Aspect="AspectFit" />
<pv:PancakeView.GestureRecognizers>
<TapGestureRecognizer Tapped="OnChangeViewButton" />
</pv:PancakeView.GestureRecognizers>
</pv:PancakeView>
<Grid/>
If MyWordListView is visible, AddWordsView is not visible and vise versa.
The App starts with MyWordListPage visible and MyWordPage.xaml.cs looks like this:
public MyWordPage()
{
InitializeComponent();
// My second content view AddWordsView take content form a content page
// this content page name is MyAddWordPage
AddWordsView.Content = new MyAddWordPage().Content;
//My list of words
ListOfWords.ItemsSource = new List<string>()
{
"New York",
"London",
"Mumbai",
"Chicago"
};
}
//I navigate between the 2 View With an Overlay Button that make
//each one of View visible thanks to a boolean
bool ViewChange=false;
void OnChangeViewButton(System.Object sender, System.EventArgs e)
{
if (ViewChange==false)
{
AddWordsView.IsVisible=true;
MyWordListView.IsVisible=false;
ViewChange=!ViewChange;
}
else
{
AddWordsView.IsVisible=false;
MyWordListView.IsVisible=true;
ViewChange=!ViewChange;
}
}
OnUpdateMyList()
{
// Here I do things to refresh my list
}
MyAddWordPage.xaml.cs looks like this :
public MyWordPage()
{
InitializeComponent();
}
void OnInsertWord(System.Object sender, System.EventArgs e)
{
}
What I would like to do :
In MyAddWordPage.xaml.cs when clicking on a button to launch the function OnInsertWord() I would like to launch the function OnUpdateMyList() in MyWordPage.xaml.cs in order to refresh My collectionView in MyWordListView
Thanks for your help
According to your requirement, you can achieve this by overriding OnAppearing method.
The OnAppearing method is executed after the ContentPage is laid out, but just before it becomes visible.So, you can rebind the list to the collectionview in this method. Therefore, this is a good place to set the content of Xamarin.Forms views.
Here is the code in MyWordPage.xaml.cs:
public MainPage()
{
InitializeComponent();
// My second content view AddWordsView take content form a content page
// this content page name is MyAddWordPage
AddWordsView.Content = new MyAddWordPage().Content;
//My list of words
}
//Create a list
List<string> list = new List<string>()
{
"New York",
"London",
"Mumbai",
"Chicago"
};
protected override void OnAppearing()
{
base.OnAppearing();
ListOfWords.ItemsSource = list;
}
//I navigate between the 2 View With an Overlay Button that make
//each one of View visible thanks to a boolean
bool ViewChange = false;
void OnChangeViewButton(System.Object sender, System.EventArgs e)
{
if (ViewChange == false)
{
AddWordsView.IsVisible = true;
MyWordListView.IsVisible = false;
ViewChange = !ViewChange;
}
else
{
AddWordsView.IsVisible = false;
MyWordListView.IsVisible = true;
ViewChange = !ViewChange;
}
}
}
Here is the code in MyWordPage.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="App5.MainPage">
<StackLayout>
<StackLayout x:Name="MyWordListView">
<CollectionView x:Name="ListOfWords" SelectionMode="Single" >
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout >
<Label Text="{Binding .}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
<ContentView IsVisible="False" x:Name="AddWordsView" >
<Label Text="Here is the text."></Label>
</ContentView>
<StackLayout>
<Button Clicked="OnChangeViewButton"></Button>
</StackLayout>
</StackLayout>
</ContentPage>

XAML Data Binding value not refreshing inside two ContentPages

I am trying to output a value from my object to two different entries. Both entries are on the same view but in different ContentPages as follows:
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myApp.Views.ViewTabs.ViewHome"
xmlns:localTabs="clr-namespace:myApp.Views.ViewTabs"
xmlns:localObjPages="clr-namespace:myApp.Objects"
>
<ContentPage Title="PageOne">
<ContentPage.BindingContext>
<localObjPages:PagesObj/>
</ContentPage.BindingContext>
<ScrollView>
<StackLayout>
<Entry
x:Name="EntryOne" Text="{Binding BananaCount}"/>
<Entry
x:Name="EntryTwo" Text="{Binding BananaCount}"/>
</StackLayout>
</ScrollView>
</ContentPage>
<ContentPage Title="PageTwo">
<ContentPage.BindingContext>
<localObjPages:PagesObj/>
</ContentPage.BindingContext>
<ScrollView>
<StackLayout>
<Entry
x:Name="EntryThree" Text="{Binding BananaCount}"/>
</StackLayout>
</ScrollView>
</ContentPage>
</TabbedPage>
My Model:
public string BananaCount
{
get { return _bananaCount; }
set
{
if (_bananaCount != value)
{
_bananaCount = value;
NotifyPropertyChanged("BananaCount");
}
}
}
The object is updated and returned in EntryOne or in EntryTwo when I change it either in EntryOne or in EntryTwo. However, it is not updated in EntryThree. Why is this? Am I Binding this correctly? Thank you.
The object is updated and returned in EntryOne or in EntryTwo when I change it either in EntryOne or in EntryTwo. However, it is not updated in EntryThree. Why is this? Am I Binding this correctly?
Do one sample about TabbedPage, assign datasource for TabbedPage, not contentpage, that you can take a look:
<TabbedPage
x:Class="FormsSample.tabbedpage.TabbedPage6"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:FormsSample.tabbedpage">
<!--Pages can be added as references or inline-->
<ContentPage Title="PageOne">
<ScrollView>
<StackLayout>
<Entry x:Name="EntryOne" Text="{Binding str}" />
<Entry x:Name="EntryTwo" Text="{Binding str}" />
<Button
x:Name="btn1"
Clicked="btn1_Clicked"
Text="change data" />
</StackLayout>
</ScrollView>
</ContentPage>
<ContentPage Title="PageTwo">
<ScrollView>
<StackLayout>
<Entry x:Name="EntryThree" Text="{Binding str}" />
</StackLayout>
</ScrollView>
</ContentPage>
public partial class TabbedPage6 : TabbedPage
{
public tabclass tabc { get; set; }
public TabbedPage6()
{
InitializeComponent();
tabc = new tabclass();
this.BindingContext = tabc;
}
private void btn1_Clicked(object sender, EventArgs e)
{
tabc.str = "this is test!";
}
}
public class tabclass:ViewModelBase
{
private string _str;
public string str
{
get { return _str; }
set
{
_str = value;
RaisePropertyChanged("str");
}
}
}
The ViewModel is one class that implement INotifyPropertyChanged.
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

Xamarin - Binding command inside stacklayout datatemplate not working

Trying to fire a command inside a stacklayout with itemssource. I wonder why the NavigateToProductListViewShopTappedCommand is not getting fired.
Tried multiple command approaches:
1)
Command="{Binding Source={RelativeSource AncestorType={x:Type local:MyShopsListViewModel}}, Path=NavigateToProductListViewShopTappedCommand}"
Command="{Binding BindingContext.NavigateToProductListViewShopTappedCommand, Source={x:Reference Page}}"
Command="{Binding Path=BindingContext.NavigateToProductListViewShopTappedCommand, Source={x:Reference Page}}"
None are not working
Code:
<?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:controls="clr-namespace:BoerPlaza.Controls.Shop"
xmlns:local="clr-namespace:BoerPlaza.ViewModels"
xmlns:behaviors="clr-namespace:BoerPlaza.Behaviors"
x:Class="BoerPlaza.Views.Shop.MyShopsPage"
x:Name="Page"
Title="Mijn winkels">
<ContentPage.Content>
<ScrollView>
<StackLayout Margin="{StaticResource margin-side-std}"
Padding="{StaticResource padding-top-bottom-std}"
BindableLayout.ItemsSource="{Binding Shops}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<controls:ShopCardTemplateView Shop="{Binding .}"
ControlTemplate="{StaticResource ShopCardTemplateView}">
<controls:ShopCardTemplateView.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1"
Command="{Binding Source={RelativeSource AncestorType={x:Type local:MyShopsListViewModel}}, Path=NavigateToProductListViewShopTappedCommand}"
CommandParameter="{Binding .}">
<!--Command="{Binding BindingContext.NavigateToProductListViewShopTappedCommand, Source={x:Reference Page}}"-->
</TapGestureRecognizer>
</controls:ShopCardTemplateView.GestureRecognizers>
</controls:ShopCardTemplateView>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
</ContentPage.Content>
</ContentPage>
Code behind
public partial class MyShopsPage : ContentPage
{
private readonly MyShopsListViewModel _viewModel;
public MyShopsPage()
{
InitializeComponent();
BindingContext = _viewModel = new MyShopsListViewModel(App.ShopDataStore, App.DialogService);
_viewModel.LoadShopsOnUserIdCommand.Execute("B22698B8-42A2-4115-9631-1C2D1E2AC5F7");
}
protected override void OnAppearing()
{
base.OnAppearing();
_viewModel.OnAppearing();
}
}
ViewModel:
[QueryProperty(nameof(UserId), nameof(UserId))]
public class MyShopsListViewModel : BaseViewModel
{
private string _userId;
private ObservableCollection<ShopDbViewModel> _shops;
private readonly IShopDataStore _shopDataStore;
private readonly IDialogService _dialogService;
public ObservableCollection<ShopDbViewModel> Shops
{
get
{
return _shops;
}
set
{
_shops = value;
OnPropertyChanged(nameof(Shops));
}
}
public void OnAppearing()
{
IsBusy = true;
}
public ICommand LoadShopsOnUserIdCommand { get; set; }
public ICommand NavigateToProductListViewShopTappedCommand { get; set; }
public MyShopsListViewModel(IShopDataStore shopDataStore, IDialogService dialogService)
{
this._shopDataStore = shopDataStore;
this._dialogService = dialogService;
Shops = new ObservableCollection<ShopDbViewModel>();
LoadShopsOnUserIdCommand = new Command<string>(async (string userId) => await ExecuteLoadShopsOnUserId(userId));
NavigateToProductListViewShopTappedCommand = new Command<ShopDbViewModel>(async (ShopDbViewModel shop) => await ExecuteNavigateToProductListViewShopTappedCommandAsync(shop));
}
private async Task ExecuteNavigateToProductListViewShopTappedCommandAsync(ShopDbViewModel shop)
{
if (shop == null)
return;
await Shell.Current.GoToAsync($"{nameof(ProductsPage)}?{nameof(MyProductsListViewModel.ShopId)}={shop.Id}");
}
public string UserId
{
get
{
return _userId;
}
set
{
_userId = value;
LoadShopsOnUserIdCommand.Execute(value);
}
}
private async Task ExecuteLoadShopsOnUserId(string userId)
{
var current = Connectivity.NetworkAccess;
if (current == NetworkAccess.Internet)
{
try
{
Shops.Clear();
var shops = await _shopDataStore.GetShopOnUserIdAsync(userId);
foreach(var shop in shops)
{
Shops.Add(shop);
}
}
catch (Exception ex)
{
await _dialogService.ShowDialog(ex.Message, "An error has occurred", "OK");
}
finally
{
IsBusy = false;
}
}
else
{
await _dialogService.ShowDialog("No active internet connection", "Connection error", "OK");
IsBusy = false;
}
}
}
If you define the ICommand in the ViewModel directly , you could set the binding path like following
Command="{Binding Path=BindingContext.NavigateToProductListViewShopTappedCommand, Source={x:Reference Page}}"
I've found the problem
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ffimage="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:customcontrols="clr-namespace:BoerPlaza.Controls"
x:Class="BoerPlaza.Controls.Shop.ShopCardTemplateView">
<ContentView.Resources>
<ControlTemplate x:Key="ShopCardTemplateView">
<!-- Card Header -->
<!-- for displaying products and categories on homepage -->
<StackLayout Spacing="1"
HorizontalOptions="FillAndExpand"
Margin="{StaticResource margin-card}">
<!-- On click - shows the product detail view page -->
<StackLayout.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" />
</StackLayout.GestureRecognizers>
<!-- Image frame -->
<Frame BackgroundColor="{StaticResource image-box-color}"
CornerRadius="0"
HasShadow="False"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HeightRequest="100">
<!-- Product Image -->
....
As you can see this is the control template I'm using for the MyShopsPage. This is a shop card. Inside this shop card I already had an StackLayout.GestureRecognizers. Somehow when I was clicking on the control template, I was actually clicking on this.
I always thought everything flows from top to bottom in events, but this seems different. Something that is on top on something else does not mean anything in xaml.

Nested ListView is not working in xamarin forms

Nested list view is not working, I have a list which contains another list in it. To show it in View I am using Nested listview; But the code is not working,and i am not able to identify on where it went wrong... Below is my code
Main Page
<ContentPage.Content>
<StackLayout>
<ListView x:Name="outerListview" ItemsSource="{Binding lst}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell x:Name="outerListviewCell">
<ViewCell.View>
<ContentView>
<Label Text="{Binding ItemName}"/>
<StackLayout>
<ListView ItemsSource="{Binding ItemList}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell x:Name="InnerListviewCell">
<Grid>
<Label Text="{Binding stockQty}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentView>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
ViewModel
public MainPageViewModel()
{
lst = new ObservableCollection<A>()
{
new A()
{
ItemName="Item1", ItemList=new ObservableCollection<ItemDetails>()
{
new ItemDetails() { stockQty="2"},
new ItemDetails(){ stockQty="3"}
}
},
new A()
{
ItemName="Item2", ItemList=new ObservableCollection<ItemDetails>()
{
new ItemDetails() { stockQty="3"},
new ItemDetails(){ stockQty="4"}
}
}
};
}
Model ( Class A and Class Itemdetails)
class A:INotifyPropertyChanged
{
public A()
{
ItemName = string.Empty;
ItemList = new ObservableCollection<ItemDetails>();
}
private string _ItemName;
public string ItemName
{
get { return _ItemName; }
set { _ItemName = value; OnPropertyChanged(); }
}
private ObservableCollection<ItemDetails> _itemlist;
public ObservableCollection<ItemDetails> ItemList
{
get { return _itemlist; }
set { _itemlist = value; OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
class ItemDetails:INotifyPropertyChanged
{
private string _stockQty;
public string stockQty
{
get { return _stockQty; }
set { _stockQty = value; OnPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
When I Run the above code I am getting below output in screen
2
3
What is expected actually is
Item1
2
3
Item2
3
4
What is wrong in above code? could anyone can help me?
Nesting Listview inside another Listview is not a good idea and it is not a supported on Xamarin.Forms.
ListView is very "sensitive" and it can easialy cause problems with scrolling and of course there are problems with poor performance of your app.
So I strongly recommend you to rethink about your layout and take a look at Grouping with ListView more about it here, maybe you can achieve what you want with Grouping.
After checking your code , I found something need to modify in your code.
In order to show the ItemName , you should wrap Label inside StackLayout .
In order to get Uneven Row, you should set listview.HasUnevenRows = true.
Modify your code as below:
<ContentPage.Content>
<ListView x:Name="outerListview" HasUnevenRows="True" ItemsSource="{Binding lst}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell x:Name="outerListviewCell">
<ViewCell.View>
<ContentView>
<StackLayout>
<Label Text="{Binding ItemName}"/>
<ListView ItemsSource="{Binding ItemList}" RowHeight="20">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell x:Name="InnerListviewCell">
<Grid>
<Label Text="{Binding stockQty}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentView>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
That is absolutely wrong. You must use one ListView with IsGroupingEnabled set to True.
Follow instuctions here to make it work correct: https://xamarinhelp.com/xamarin-forms-listview-grouping/