Skip to content

Instantly share code, notes, and snippets.

@albilaga
Created May 10, 2018 06:13
Show Gist options
  • Save albilaga/00c8c9cca51050f81974216770d1bf1d to your computer and use it in GitHub Desktop.
Save albilaga/00c8c9cca51050f81974216770d1bf1d to your computer and use it in GitHub Desktop.
Horizontal List View for xamarin forms
using System;
using System.Collections;
using System.Collections.Specialized;
using Xamarin.Forms;
namespace Pradana.CustomControls
{
public delegate void RepeaterViewItemAddedEventHandler(object sender, RepeaterViewItemAddedEventArgs args);
public class HorizontalListView : ScrollView, IDisposable
{
private StackLayout rootLayout;
public HorizontalListView()
{
this.Orientation = ScrollOrientation.Horizontal;
rootLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal
};
this.Content = rootLayout;
}
#region Properties
public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(
propertyName: "ItemsSource",
returnType: typeof(IEnumerable),
declaringType: typeof(HorizontalListView),
defaultValue: null,
defaultBindingMode: BindingMode.OneWay,
propertyChanged: ItemsChanged);
public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create(
propertyName: "ItemTemplate",
returnType: typeof(DataTemplate),
declaringType: typeof(HorizontalListView),
defaultValue: default(DataTemplate));
public event RepeaterViewItemAddedEventHandler ItemCreated;
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
#endregion
private static void ItemsChanged(BindableObject bindable, object oldValue, object newValue)
{
IEnumerable oldValueAsEnumerable;
IEnumerable newValueAsEnumerable;
try
{
oldValueAsEnumerable = oldValue as IEnumerable;
newValueAsEnumerable = newValue as IEnumerable;
}
catch (Exception e)
{
throw e;
}
var control = (HorizontalListView)bindable;
var oldObservableCollection = oldValue as INotifyCollectionChanged;
if (oldObservableCollection != null)
{
oldObservableCollection.CollectionChanged -= control.OnItemsSourceCollectionChanged;
}
var newObservableCollection = newValue as INotifyCollectionChanged;
if (newObservableCollection != null)
{
newObservableCollection.CollectionChanged += control.OnItemsSourceCollectionChanged;
}
control.rootLayout.Children.Clear();
if (newValueAsEnumerable != null)
{
foreach (var item in newValueAsEnumerable)
{
var view = control.CreateChildViewFor(item);
control.rootLayout.Children.Add(view);
control.OnItemCreated(view);
}
}
control.UpdateChildrenLayout();
control.InvalidateLayout();
}
protected virtual void OnItemCreated(View view) =>
this.ItemCreated?.Invoke(this, new RepeaterViewItemAddedEventArgs(view, view.BindingContext));
private void OnItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
var invalidate = true;
if (e.OldItems != null)
{
rootLayout.Children.RemoveAt(e.OldStartingIndex);
invalidate = true;
}
if (e.NewItems != null)
{
for (var i = 0; i < e.NewItems.Count; ++i)
{
var item = e.NewItems[i];
var view = this.CreateChildViewFor(item);
rootLayout.Children.Insert(i + e.NewStartingIndex, view);
OnItemCreated(view);
}
invalidate = true;
}
if (invalidate)
{
this.UpdateChildrenLayout();
this.InvalidateLayout();
}
}
private View CreateChildViewFor(object item)
{
this.ItemTemplate.SetValue(BindableObject.BindingContextProperty, item);
return (View)this.ItemTemplate.CreateContent();
}
public void Dispose()
{
rootLayout.Children.Clear();
rootLayout = null;
}
}
public class RepeaterViewItemAddedEventArgs : EventArgs
{
private readonly View view;
private readonly object model;
public RepeaterViewItemAddedEventArgs(View view, object model)
{
this.view = view;
this.model = model;
}
public View View => this.view;
public object Model => this.model;
}
}
@agusibrahim
Copy link

i'ts working! thnx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment