Last active
September 4, 2018 10:51
-
-
Save 15mgm15/943121c22561ef280439e11730b7a2d4 to your computer and use it in GitHub Desktop.
Xamarin.Forms Carousel View Indicators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CarouselIndicators : Grid | |
{ | |
private ImageSource UnselectedImageSource = null; | |
private ImageSource SelectedImageSource = null; | |
private readonly StackLayout _indicators = new StackLayout() { Orientation = StackOrientation.Horizontal, HorizontalOptions = LayoutOptions.CenterAndExpand }; | |
public CarouselIndicators() | |
{ | |
this.HorizontalOptions = LayoutOptions.CenterAndExpand; | |
this.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); | |
this.Children.Add(_indicators); | |
} | |
public static readonly BindableProperty PositionProperty = BindableProperty.Create(nameof(Position), typeof(int), typeof(CarouselIndicators), 0, BindingMode.TwoWay, propertyChanging: PositionChanging); | |
public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(nameof(ItemsSource), typeof(IEnumerable), typeof(CarouselIndicators), Enumerable.Empty<object>(), BindingMode.OneWay, propertyChanged: ItemsChanged); | |
public static readonly BindableProperty SelectedIndicatorProperty = BindableProperty.Create(nameof(SelectedIndicator), typeof(string), typeof(CarouselIndicators), "", BindingMode.OneWay); | |
public static readonly BindableProperty UnselectedIndicatorProperty = BindableProperty.Create(nameof(UnselectedIndicator), typeof(string), typeof(CarouselIndicators), "", BindingMode.OneWay); | |
public static readonly BindableProperty IndicatorWidthProperty = BindableProperty.Create(nameof(IndicatorWidth), typeof(double), typeof(CarouselIndicators), 0.0, BindingMode.OneWay); | |
public static readonly BindableProperty IndicatorHeightProperty = BindableProperty.Create(nameof(IndicatorHeight), typeof(double), typeof(CarouselIndicators), 0.0, BindingMode.OneWay); | |
public string SelectedIndicator | |
{ | |
get { return (string)this.GetValue(SelectedIndicatorProperty); } | |
set { this.SetValue(SelectedIndicatorProperty, value); } | |
} | |
public string UnselectedIndicator | |
{ | |
get { return (string)this.GetValue(UnselectedIndicatorProperty); } | |
set { this.SetValue(UnselectedIndicatorProperty, value); } | |
} | |
public double IndicatorWidth | |
{ | |
get { return (double)this.GetValue(IndicatorWidthProperty); } | |
set { this.SetValue(IndicatorWidthProperty, value); } | |
} | |
public double IndicatorHeight | |
{ | |
get { return (double)this.GetValue(IndicatorHeightProperty); } | |
set { this.SetValue(IndicatorHeightProperty, value); } | |
} | |
public int Position | |
{ | |
get { return (int)this.GetValue(PositionProperty); } | |
set { this.SetValue(PositionProperty, value); } | |
} | |
public IEnumerable ItemsSource | |
{ | |
get { return (IEnumerable)this.GetValue(ItemsSourceProperty); } | |
set { this.SetValue(ItemsSourceProperty, (object)value); } | |
} | |
private void Clear() | |
{ | |
_indicators.Children.Clear(); | |
} | |
private void Init(int position) | |
{ | |
if (UnselectedImageSource == null) | |
UnselectedImageSource = ImageSource.FromFile(UnselectedIndicator); | |
if (SelectedImageSource == null) | |
SelectedImageSource = ImageSource.FromFile(SelectedIndicator); | |
if (_indicators.Children.Count > 0) | |
{ | |
for (int i = 0; i < _indicators.Children.Count; i++) | |
{ | |
if (((Image)_indicators.Children[i]).ClassId == nameof(State.Selected) && i != position) | |
_indicators.Children[i] = BuildImage(State.Unselected, i); | |
else if (((Image)_indicators.Children[i]).ClassId == nameof(State.Unselected) && i == position) | |
_indicators.Children[i] = BuildImage(State.Selected, i); | |
} | |
} | |
else | |
{ | |
var enumerator = ItemsSource.GetEnumerator(); | |
int count = 0; | |
while (enumerator.MoveNext()) | |
{ | |
Image image = null; | |
if (position == count) | |
image = BuildImage(State.Selected, count); | |
else | |
image = BuildImage(State.Unselected, count); | |
_indicators.Children.Add(image); | |
count++; | |
} | |
} | |
} | |
private Image BuildImage(State state, int position) | |
{ | |
var image = new Image() | |
{ | |
WidthRequest = IndicatorWidth, | |
HeightRequest = IndicatorHeight, | |
ClassId = state.ToString() | |
}; | |
switch (state) | |
{ | |
case State.Selected: | |
image.Source = SelectedImageSource; | |
break; | |
case State.Unselected: | |
image.Source = UnselectedImageSource; | |
break; | |
default: | |
throw new Exception("Invalid state selected"); | |
} | |
image.GestureRecognizers.Add(new TapGestureRecognizer() { Command = new Command(() => { Position = position; }) }); | |
return image; | |
} | |
private static void PositionChanging(object bindable, object oldValue, object newValue) | |
{ | |
var carouselIndicators = bindable as CarouselIndicators; | |
carouselIndicators.Init(Convert.ToInt32(newValue)); | |
} | |
private static void ItemsChanged(object bindable, object oldValue, object newValue) | |
{ | |
var carouselIndicators = bindable as CarouselIndicators; | |
carouselIndicators.Clear(); | |
carouselIndicators.Init(0); | |
} | |
public enum State | |
{ | |
Selected, | |
Unselected | |
} | |
} |
@gurvinderbini You can get a sample here , I also Have a Implementation I created here
How to handle delete scenario. I mean when i delete a single image how to delete corresponding caraousel indicator
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how to implement it in xaml?