1

I am trying to implement Horizontally scrolling List view in Xamarin forms and i have tried several libraries but could not find good solution. Is this possible in Xamrin forms (without renders) and is there working library i can use?

0

3 Answers 3

1

Inorder to get a horizontal scrolling listview you have to create a custom scrollView as follow and use this custom control in XAML

public class ImageGallery : ScrollView { readonly StackLayout _imageStack;

    public ImageGallery()
    {
        this.Orientation = ScrollOrientation.Horizontal;

        _imageStack = new StackLayout
        {
            Orientation = StackOrientation.Horizontal
        };

        this.Content = _imageStack;
    }

    public IList<View> Children
    {
        get
        {
            return _imageStack.Children;
        }
    }


    public static readonly BindableProperty ItemsSourceProperty =
        BindableProperty.Create<ImageGallery, IList>(
            view => view.ItemsSource,
            default(IList),
            BindingMode.TwoWay,
            propertyChanging: (bindableObject, oldValue, newValue) => {
                ((ImageGallery)bindableObject).ItemsSourceChanging();
            },
            propertyChanged: (bindableObject, oldValue, newValue) => {
                ((ImageGallery)bindableObject).ItemsSourceChanged(bindableObject, oldValue, newValue);
            }
        );

    public IList ItemsSource
    {
        get
        {
            return (IList)GetValue(ItemsSourceProperty);
        }
        set
        {

            SetValue(ItemsSourceProperty, value);
        }
    }
    void ItemsSourceChanging()
    {
        if (ItemsSource == null)
            return;
    }
    void ItemsSourceChanged(BindableObject bindable, IList oldValue, IList newValue)
    {
        if (ItemsSource == null)
            return;

        var notifyCollection = newValue as INotifyCollectionChanged;
        if (notifyCollection != null)
        {
            notifyCollection.CollectionChanged += (sender, args) => {
                if (args.NewItems != null)
                {
                    foreach (var newItem in args.NewItems)
                    {

                        var view = (View)ItemTemplate.CreateContent();
                        var bindableObject = view as BindableObject;
                        if (bindableObject != null)
                            bindableObject.BindingContext = newItem;
                        _imageStack.Children.Add(view);
                    }
                }
                if (args.OldItems != null)
                {
                    // not supported
                    _imageStack.Children.RemoveAt(args.OldStartingIndex);
                }
            };
        }
    }
    public DataTemplate ItemTemplate
    {
        get;
        set;
    }
    public static readonly BindableProperty SelectedItemProperty =
        BindableProperty.Create<ImageGallery, object>(
            view => view.SelectedItem,
            null,
            BindingMode.TwoWay,
            propertyChanged: (bindable, oldValue, newValue) => {
                ((ImageGallery)bindable).UpdateSelectedIndex();
            }
        );

    public object SelectedItem
    {
        get
        {
            return GetValue(SelectedItemProperty);
        }
        set
        {
            SetValue(SelectedItemProperty, value);
        }
    }

    void UpdateSelectedIndex()
    {
        if (SelectedItem == BindingContext)
            return;

        SelectedIndex = Children
            .Select(c => c.BindingContext)
            .ToList()
            .IndexOf(SelectedItem);

    }

    public static readonly BindableProperty SelectedIndexProperty =
        BindableProperty.Create<ImageGallery, int>(
            carousel => carousel.SelectedIndex,
            0,
            BindingMode.TwoWay,
            propertyChanged: (bindable, oldValue, newValue) => {
                ((ImageGallery)bindable).UpdateSelectedItem();
            }
        );

    public int SelectedIndex
    {
        get
        {
            return (int)GetValue(SelectedIndexProperty);
        }
        set
        {
            SetValue(SelectedIndexProperty, value);
        }
    }

    void UpdateSelectedItem()
    {
        SelectedItem = SelectedIndex > -1 ? Children[SelectedIndex].BindingContext : null;
    }
}`

Now you can use the custom ScrollView in XAML to get a horizontal scrolling list

<custom:ImageGallery ItemsSource="{Binding ImageList}" HeightRequest="100"> <custom:ImageGallery.ItemTemplate> <DataTemplate> <-- layout and related stuffs--> </DataTemplate> </custom:ImageGallery.ItemTemplate> </custom:ImageGallery>

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you . I will try this .
0

try https://www.nuget.org/packages/HorizontalListView1.1/

Sample usage:(XAML)

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
x:Class="test.ListPage" xmlns:Controls="clr-namespace:test;assembly=test"> 

<Controls:HorizontalListView ItemsSource="{Binding Categories}" ListOrientation="Horizontal"> 
  <Controls:HorizontalListView.ItemTemplate> 
    <DataTemplate> 
    <Label Text="{Binding Name}" Grid.Row="0" YAlign="Center" /> 
    </DataTemplate> 
  </Controls:HorizontalListView.ItemTemplate> 
  </Controls:myControl>

Comments

0

Some create Horizontal ListViews by Rotating the ListView, and then Rotating back the elements.

That's a hack, you have to make sure it doesn't mess with your layout (do not put that in a Grid e.g.). But it works fine.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.