AhmedAdel
AhmedAdel

Reputation: 15

Xamarin Forms ListView inside ListView Problem

<ListView HasUnevenRows="True" x:Name="collectionView" HeightRequest="1000"
                  Margin="20">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout HeightRequest="50" Margin="10" WidthRequest="200">
                            <Label Text="{Binding Name}" FontSize="15" TextColor="Black"/>
                            <Label Text="{Binding Description}" FontSize="15" TextColor="Black"/>
                            <ListView HasUnevenRows="True" ItemsSource="{Binding appointments}" HeightRequest="1000" Margin="20,0,0,0">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <ViewCell>
                                            <StackLayout HeightRequest="100" Margin="10" WidthRequest="200">
                                                <Label Text="{Binding Name}" FontSize="15" TextColor="Black"/>
                                                <Label Text="{Binding Subject}" FontSize="15" TextColor="Black"/>
                                            </StackLayout>
                                        </ViewCell>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>  



 protected override void OnAppearing()
        {
            try
            {
                base.OnAppearing();
                var appointemntsList = new List<Appointment>()
                {
                    new Appointment() { Name="Mohamed",Subject="Sub"},
                    new Appointment() { Name="Mohamed",Subject="Sub"},
                    new Appointment() { Name="Mohamed",Subject="Sub"},
                    new Appointment() { Name="Mohamed",Subject="Sub"},
                };
                var Monkeys = new List<Appointment>()
                {
                    new Appointment() { Name="Ahmed", Description="Desc",appointments=appointemntsList},
                    new Appointment() { Name="Ahmed", Description="Desc",appointments=appointemntsList},
                    new Appointment() { Name="Ahmed", Description="Desc",appointments=appointemntsList},
                    new Appointment() { Name="Ahmed", Description="Desc",appointments=appointemntsList},

                };
                collectionView.ItemsSource = Monkeys;
            }
            catch (Exception)
            {
            }
        }  

Using This Code I need to Show List View Inside List view but not working

Upvotes: 0

Views: 875

Answers (2)

FreakyAli
FreakyAli

Reputation: 16572

What you can do is replace the inner Xamarin.Forms.ListView with the custom RepeaterView

RepeaterView is a control that inherits from stack layout and works very much like ListView but does not have its own scroll, since you already have a ListView i.e. "scroll" it should work great for you.

public class RepeaterView<T> : StackLayout where T : class
{
    public static readonly BindableProperty HeaderTemplateProperty = BindableProperty.Create(nameof(HeaderTemplate), typeof(DataTemplate), typeof(RepeaterView<T>), default(DataTemplate));

    public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create(nameof(ItemTemplate), typeof(DataTemplate), typeof(RepeaterView<T>), default(DataTemplate));

    public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(nameof(ItemsSource), typeof(IEnumerable<T>), typeof(RepeaterView<T>), null, defaultBindingMode: BindingMode.OneWay, propertyChanged: ItemsChanged);

    public RepeaterView()
    {
        Spacing = 0;
    }

    public IEnumerable<T> ItemsSource
    {
        get { return (IEnumerable<T>)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public DataTemplate ItemTemplate
    {
        get { return (DataTemplate)GetValue(ItemTemplateProperty); }
        set { SetValue(ItemTemplateProperty, value); }
    }

    public DataTemplate HeaderTemplate
    {
        get { return (DataTemplate)GetValue(HeaderTemplateProperty); }
        set { SetValue(HeaderTemplateProperty, value); }
    }

    protected virtual View ViewFor(T item)
    {
        View view = null;
        if (ItemTemplate != null)
        {
            var content = ItemTemplate.CreateContent();
            view = (content is View) ? content as View : ((ViewCell)content).View;

            view.BindingContext = item;
        }

        return view;
    }

    protected View HeaderView()
    {
        View view = null;

        if (HeaderTemplate != null)
        {
            var content = HeaderTemplate.CreateContent();
            view = (content is View) ? content as View : ((ViewCell)content).View;
            view.BindingContext = this.BindingContext;
        }

        return view;
    }

    private static void ItemsChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = bindable as RepeaterView<T>;
        if (control == null)
            return;

        control.Children.Clear();

        IEnumerable<T> items = (IEnumerable<T>)newValue;
        if (items.Any())
        {
            var header = control.HeaderView();
            if (header != null)
                control.Children.Add(header);

            foreach (var item in items)
                control.Children.Add(control.ViewFor(item));
        }
    }
}

For better understanding of how this control works, you can check the guide here

Feel free to revert if you have queries

Upvotes: 1

Himanshu Dwivedi
Himanshu Dwivedi

Reputation: 8124

You need to write a Custom renderer for the ListView to enable Nested Scrolling for the ListView for Android:

public class NestedListViewRenderer: ListViewRenderer {
 Context _context;

 public NestedListViewRenderer(Context context): base(context) {
  _context = context;
 }

 protected override void OnElementChanged(ElementChangedEventArgs < Xamarin.Forms.ListView > e) {
  base.OnElementChanged(e);

  if (e.NewElement != null) {
   var listView = this.Control as Android.Widget.ListView;
   listView.NestedScrollingEnabled = true;
  }
 }
}

Note: This is not recommended as it may affect LisView Performance.

Upvotes: 0

Related Questions