1

I'm creating a Prism Xamarin Form app, in my page I have nested listviews (4 levels), the problem is that I'm not able to raise event when I tap on an item inside second, third and fourth level listviews, the event is working only for the top level listview, knowing that the 4 listviews have the same item source type.

I searched a lot concerning how to raise event when I tap item of a list view that exists inside another parent list view and I got not answer that fit my case, I tried to method:

1-

ItemSelected = {Binding SelectedItem}

2-

EventToCommandBehavior EventName="ItemTapped" Command="{Binding SelectCustomEntityCommand}" EventArgsConverter="{converters:ItemTappedEventArgsConverter}"

The following are the code structures:

1- CustomEntity Class

public class CustomEntity 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Expanded { get; set; }
    public List<CustomEntity> LevelTwo { get; set; }
    public List<CustomEntity> LevelThree { get; set; }
    public List<CustomEntity> LevelFour { get; set; }
}

2- testNestedListViewsViewModel Class

public class testNestedListViewsViewModel : ViewModelBase
{
    public testNestedListViewsViewModel(INavigationService navigationService)
        : base(navigationService)
    {
        Title = "Test Nested Listviews";
        LevelOne = new ObservableCollection<CustomEntity>();
    }


    private ObservableCollection<CustomEntity> _LevelOne;
    public ObservableCollection<CustomEntity> LevelOne
    {
        get { return _LevelOne; }
        set { SetProperty(ref _LevelOne, value); }
    }

    private DelegateCommand<CustomEntity> _selectCustomEntity;
    public DelegateCommand<CustomEntity> SelectCustomEntityCommand => _selectCustomEntity ?? (_selectCustomEntity = new DelegateCommand<CustomEntity>(ShowCustomEntityDetails));

    private void ShowCustomEntityDetails(CustomEntity paramData)
    {
        var x = paramData;
    }



    public override void OnNavigatingTo(INavigationParameters parameters)
    {
        for (int i = 0; i < 10; i++)
        {
            LevelOne.Add(new CustomEntity() { Id = i + 1, Name = "Name " + (i + 1), Expanded = false });
        }
        foreach (var item in LevelOne)
        {
            item.LevelTwo = new List<CustomEntity>();
            item.LevelTwo.Add(new CustomEntity() { Id = 100, Name = "K", Expanded = false });
            item.LevelTwo.Add(new CustomEntity() { Id = 101, Name = "1", Expanded = false });
            item.LevelTwo.Add(new CustomEntity() { Id = 102, Name = "2", Expanded = false });
            item.LevelTwo.Add(new CustomEntity() { Id = 103, Name = "3", Expanded = false });
            item.LevelTwo.Add(new CustomEntity() { Id = 104, Name = "4", Expanded = false });
            item.LevelTwo.Add(new CustomEntity() { Id = 105, Name = "5", Expanded = false });
            foreach (var item2 in item.LevelTwo)
            {
                item2.LevelThree = new List<CustomEntity>();
                item2.LevelThree.Add(new CustomEntity() { Id = 200, Name = "BOK 1", Expanded = false });
                item2.LevelThree.Add(new CustomEntity() { Id = 201, Name = "BOK 2", Expanded = false });
                item2.LevelThree.Add(new CustomEntity() { Id = 202, Name = "BOK 3", Expanded = false });
                item2.LevelThree.Add(new CustomEntity() { Id = 203, Name = "BOK 4", Expanded = false });
                item2.LevelThree.Add(new CustomEntity() { Id = 204, Name = "BOK 5", Expanded = false });
                item2.LevelThree.Add(new CustomEntity() { Id = 205, Name = "BOK 6", Expanded = false });
            }
        }
    }

}

3- Xaml file

      <Label Text="{Binding Title}" />

      <ListView Grid.Row="1"
                BackgroundColor="White"
                SeparatorColor="Gray"
                ItemsSource="{Binding LevelOne}"
                VerticalOptions="Fill">
          <ListView.Behaviors>
              <b:EventToCommandBehavior EventName="ItemTapped" 
                                        Command="{Binding SelectCustomEntityCommand}"
                                        EventArgsConverter="{converters:ItemTappedEventArgsConverter}" />
          </ListView.Behaviors>
          <ListView.ItemTemplate>
              <DataTemplate>
                  <ViewCell>
                      <Grid>
                          <Grid.RowDefinitions>
                              <RowDefinition Height="Auto"/>
                              <RowDefinition Height="Auto"/>
                          </Grid.RowDefinitions>
                          <Label Grid.Row="0" Text="{Binding Name}" TextColor="Blue"></Label>
                          <ListView Grid.Row="1"
                                BackgroundColor="White"
                                SeparatorColor="Gray"
                                ItemsSource="{Binding LevelTwo}"
                                VerticalOptions="Fill">       
                              <ListView.Behaviors>
                                  <b:EventToCommandBehavior EventName="ItemTapped" 
                                        Command="{Binding SelectCustomEntityCommand}"
                                        EventArgsConverter="{converters:ItemTappedEventArgsConverter}" />
                              </ListView.Behaviors>
                              <ListView.ItemTemplate>
                                  <DataTemplate>
                                      <ViewCell>
                                          <Grid>
                                              <Grid.RowDefinitions>
                                                  <RowDefinition Height="Auto"/>
                                                  <RowDefinition Height="Auto"/>
                                              </Grid.RowDefinitions>
                                              <Label Grid.Row="0" Text="{Binding Name}" TextColor="Red"></Label>

                                          </Grid>
                                      </ViewCell>
                                  </DataTemplate>
                              </ListView.ItemTemplate>
                          </ListView>
                      </Grid>
                  </ViewCell>
              </DataTemplate>
          </ListView.ItemTemplate>            

I expected when I tap on an item in the second listview to raise the event named: "SelectCustomEntityCommand" But I noticed that only first level listview raise that event.

Fadl Assaad
  • 99
  • 13
  • 1
    Nesting listviews is not a good practice, to begin with, and hence you are facing these issues and discrepancies – FreakyAli Jun 19 '19 at 09:33
  • @G.hakim I appreciate your comment, but I really believe that everything can be done in programming, but since I have little experience in XAML work so I'm slow to do some progress on this. – Fadl Assaad Jun 19 '19 at 09:42
  • Actually, not everything can be done in programming anyway you might wanna read this https://forums.xamarin.com/discussion/100280/nested-listview-in-xamarin-forms-listview-inside-another-listview – FreakyAli Jun 19 '19 at 09:46
  • Ok @G.hakim thanks a lot, do you think is possible to call a method in the CustomEntity class that envoke an event on testNestedListViewsViewModel? I mean some kind of method reference or something, I don't know if that is possible – Fadl Assaad Jun 19 '19 at 10:31
  • You can check out messaging center for this https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/messaging-center – FreakyAli Jun 19 '19 at 11:04
  • why do you even need a 4 level nested ListViews? i think this might be a XY problem, hence the reasson you are encountering this issues, can you explain why you need a ListView inside a ListView inside (...)?? – Ricardo Dias Morais Jun 19 '19 at 11:10
  • @G.hakim I read the link you provided, unfortunately, this does not support MVVM Prism Framework, I actually need something like that, I need to subscribe a message and then to fire it with some arguments when I put a method inside CustomEntity class it fired when I tap on the second level listview but I need then to have an event in the main page to be fired. – Fadl Assaad Jun 19 '19 at 11:24
  • @RicardoDiasMorais I have a client specs that needs to browse some Standards in the following hierarchical: Subject > Grade Level > Domain > Topic, so that the user can browse for standards using that tree of listviews – Fadl Assaad Jun 19 '19 at 11:26
  • Have you tried RepeaterView? https://www.nuget.org/packages/Xamarin.CustomControls.RepeaterView/; like the Name Says, it repeates views, so you can use a ScrollView with a RepeaterView inside RepeaterView inside (...), with will give you what you want – Ricardo Dias Morais Jun 19 '19 at 11:31
  • but here is an warning: this method doesn't use the ListView Recycling method, your list views have images? if they have or you have alot of items binded, it might not be a good solution – Ricardo Dias Morais Jun 19 '19 at 11:33
  • Thanks @RicardoDiasMorais I will give it a try – Fadl Assaad Jun 19 '19 at 12:12

0 Answers0