From 8e477bbe9f88d490138ea3d8b4f26c2634b38978 Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Fri, 7 Oct 2016 14:27:38 +0200 Subject: [PATCH] A star behavior! --- BookAStar/BookAStar/Behaviors/StarBehavior.cs | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 BookAStar/BookAStar/Behaviors/StarBehavior.cs diff --git a/BookAStar/BookAStar/Behaviors/StarBehavior.cs b/BookAStar/BookAStar/Behaviors/StarBehavior.cs new file mode 100644 index 00000000..c73350f5 --- /dev/null +++ b/BookAStar/BookAStar/Behaviors/StarBehavior.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xamarin.Forms; + +namespace BookAStar.Behaviors +{ + public class StarBehavior : Behavior + { + TapGestureRecognizer tapRecognizer; + static List defaultBehaviors = new List(); + static Dictionary> starGroups = new Dictionary>(); + + public static readonly BindableProperty GroupNameProperty = + BindableProperty.Create("GroupName", + typeof(string), + typeof(StarBehavior), + null, + propertyChanged: OnGroupNameChanged); + + public string GroupName + { + set { SetValue(GroupNameProperty, value); } + get { return (string)GetValue(GroupNameProperty); } + } + + public static readonly BindableProperty RatingProperty = + BindableProperty.Create("Rating", + typeof(int), + typeof(StarBehavior), default(int), + BindingMode.TwoWay); + + public int Rating + { + set { SetValue(RatingProperty, value); } + get { return (int)GetValue(RatingProperty); } + } + + static void OnGroupNameChanged(BindableObject bindable, object oldValue, object newValue) + { + StarBehavior behavior = (StarBehavior)bindable; + string oldGroupName = (string)oldValue; + string newGroupName = (string)newValue; + + // Remove existing behavior from Group + if (String.IsNullOrEmpty(oldGroupName)) + { + defaultBehaviors.Remove(behavior); + } + else + { + List behaviors = starGroups[oldGroupName]; + behaviors.Remove(behavior); + + if (behaviors.Count == 0) + { + starGroups.Remove(oldGroupName); + } + } + + // Add New Behavior to the group + if (String.IsNullOrEmpty(newGroupName)) + { + defaultBehaviors.Add(behavior); + } + else + { + List behaviors = null; + + if (starGroups.ContainsKey(newGroupName)) + { + behaviors = starGroups[newGroupName]; + } + else + { + behaviors = new List(); + starGroups.Add(newGroupName, behaviors); + } + + behaviors.Add(behavior); + } + } + + public static readonly BindableProperty IsStarredProperty = + BindableProperty.Create("IsStarred", + typeof(bool), + typeof(StarBehavior), + false, + propertyChanged: OnIsStarredChanged); + + public bool IsStarred + { + set { SetValue(IsStarredProperty, value); } + get { return (bool)GetValue(IsStarredProperty); } + } + + static void OnIsStarredChanged(BindableObject bindable, object oldValue, object newValue) + { + StarBehavior behavior = (StarBehavior)bindable; + + if ((bool)newValue) + { + string groupName = behavior.GroupName; + List behaviors = null; + + if (string.IsNullOrEmpty(groupName)) + { + behaviors = defaultBehaviors; + } + else + { + behaviors = starGroups[groupName]; + } + + bool itemReached = false; + int count = 1, position = 0; + // all positions to left IsStarred = true and all position to the right is false + foreach (var item in behaviors) + { + if (item != behavior && !itemReached) + { + item.IsStarred = true; + } + if (item == behavior) + { + itemReached = true; + item.IsStarred = true; + position = count; + } + if (item != behavior && itemReached) + item.IsStarred = false; + + item.Rating = position; + count++; + } + + } + + + } + + public StarBehavior() + { + defaultBehaviors.Add(this); + } + + protected override void OnAttachedTo(View view) + { + tapRecognizer = new TapGestureRecognizer(); + tapRecognizer.Tapped += OnTapRecognizerTapped; + view.GestureRecognizers.Add(tapRecognizer); + } + + protected override void OnDetachingFrom(View view) + { + view.GestureRecognizers.Remove(tapRecognizer); + tapRecognizer.Tapped -= OnTapRecognizerTapped; + } + + void OnTapRecognizerTapped(object sender, EventArgs args) + { + // TODO HACK: PropertyChange does not fire, if the value is not changed :-( + IsStarred = false; + IsStarred = true; + } + } +}