/// <summary>
        /// Set the strokes
        /// </summary>
        /// <param name="inkStrokes">the new ink strokes</param>
        public void SetRange(IEnumerable <XInkStroke> inkStrokes)
        {
            DeleteStrokes();

            AddStrokes(inkStrokes);

            InkChanged?.Invoke(this, new EventArgs());
        }
        /// <summary>
        /// Add an ink stroke to the container
        /// </summary>
        /// <param name="stroke">the stroke to add</param>
        public void Add(XInkStroke stroke)
        {
            lock (_inkStrokes)
            {
                _inkStrokes.Add(stroke);

                InkChanged?.Invoke(this, new EventArgs());
            }
        }
        /// <summary>
        /// Adds ink strokes
        /// </summary>
        /// <param name="strokes">a collection of ink strokes</param>
        public void Add(IEnumerable <XInkStroke> strokes)
        {
            lock (_inkStrokes)
            {
                _inkStrokes.AddRange(strokes);

                InkChanged?.Invoke(this, new EventArgs());
            }
        }
        //public void Deserialize(string json)
        //{
        //    Dispose();

        //    var strokes = JsonConvert.DeserializeObject<List<InkStroke>>(json);

        //    Strokes.ForEach(delegate (InkStroke stroke)
        //    {
        //        if (stroke.Color.A == 0)
        //        {
        //            stroke.Color = Xamarin.Forms.Color.FromRgba(stroke.Color.R, stroke.Color.G, stroke.Color.B, 255);
        //        }

        //        stroke.UpdateBounds();
        //    });
        //}

        //public string Serialize()
        //{
        //    return JsonConvert.SerializeObject(Strokes);
        //}
        /// <summary>
        /// Dispose of the strokes
        /// </summary>
        public void Dispose()
        {
            _inkStrokes.ForEach(delegate(XInkStroke stroke)
            {
                stroke.Dispose();
            });

            _inkStrokes.Clear();

            InkChanged?.Invoke(this, new EventArgs());
        }
        /// <summary>
        /// Add a stroke
        /// </summary>
        /// <param name="inkStroke">the ink stroke to add</param>
        public void Add(XInkStroke inkStroke)
        {
            var newStroke = inkStroke.ToInkStroke();

            if (newStroke == null)
            {
                return;
            }

            NativeStrokeContainer.AddStroke(newStroke);

            InkChanged?.Invoke(this, new EventArgs());
        }
        /// <summary>
        /// Sets the ink strokes
        /// </summary>
        /// <param name="inkStrokes">a collection of ink strokes</param>
        public void SetRange(IEnumerable <XInkStroke> inkStrokes)
        {
            lock (_inkStrokes)
            {
                _inkStrokes.ForEach(delegate(XInkStroke stroke)
                {
                    stroke.Dispose();
                });
                _inkStrokes.Clear();

                _inkStrokes.AddRange(inkStrokes);
            }

            InkChanged?.Invoke(this, new EventArgs());
        }
        /// <summary>
        /// Remove the ink stroke
        /// </summary>
        /// <param name="item">the ink stroke</param>
        public void Remove(XInkStroke item)
        {
            if (item == null)
            {
                return;
            }

            lock (_inkStrokes)
            {
                item.Dispose();

                _inkStrokes.Remove(item);
            }

            InkChanged?.Invoke(this, new EventArgs());
        }
        /// <summary>
        /// Remove the strokes
        /// </summary>
        /// <param name="strokesToRemove">the strokes to remove</param>
        public void Remove(IReadOnlyList <XInkStroke> strokesToRemove)
        {
            var ids = from item in strokesToRemove
                      select item.Id;

            foreach (var stroke in NativeStrokeContainer.GetStrokes())
            {
                if (ids.Contains(stroke.Id.ToString(CultureInfo.InvariantCulture)))
                {
                    stroke.Selected = true;
                }
            }

            NativeStrokeContainer.DeleteSelected();

            InkChanged?.Invoke(this, new EventArgs());
        }
        /// <summary>
        /// Add a collection of strokes.
        /// </summary>
        /// <param name="strokes">the strokes to add</param>
        private void AddStrokes(IEnumerable <XInkStroke> strokes)
        {
            if (strokes == null)
            {
                throw new ArgumentNullException(nameof(strokes));
            }

            var strokesToAdd = from item in strokes
                               let newStroke = item.ToInkStroke()
                                               where newStroke != null
                                               select newStroke;

            foreach (var item in strokesToAdd)
            {
                NativeStrokeContainer.AddStroke(item);
            }

            InkChanged?.Invoke(this, new EventArgs());
        }
        /// <summary>
        /// Remove an ink stroke
        /// </summary>
        /// <param name="item">the stroke to remove</param>
        public void Remove(XInkStroke item)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            foreach (var stroke in NativeStrokeContainer.GetStrokes())
            {
                if (stroke.Id.ToString(CultureInfo.InvariantCulture) == item.Id)
                {
                    stroke.Selected = true;
                }
            }

            NativeStrokeContainer.DeleteSelected();

            InkChanged?.Invoke(this, new EventArgs());
        }
        /// <summary>
        /// remove a list of strokes
        /// </summary>
        /// <param name="strokesToRemove">the strokes to remove</param>
        public void Remove(IReadOnlyList <XInkStroke> strokesToRemove)
        {
            if (strokesToRemove == null)
            {
                throw new ArgumentNullException(nameof(strokesToRemove));
            }

            lock (_inkStrokes)
            {
                foreach (var item in strokesToRemove)
                {
                    item.Dispose();

                    _inkStrokes.Remove(item);
                }
            }

            InkChanged?.Invoke(this, new EventArgs());
        }
        /// <summary>
        /// Remove all of the ink stroks from the container
        /// </summary>
        public void Clear()
        {
            lock (_inkStrokes)
            {
                var args = new XInkStrokesErasedEventArgs(_inkStrokes.ToList());

                if (_inkStrokes.Any())
                {
                    _inkStrokes.ForEach(delegate(XInkStroke item)
                    {
                        item.Dispose();
                    });

                    _inkStrokes.Clear();

                    InkChanged?.Invoke(this, new EventArgs());
                }
            }

            GC.Collect();
        }
        /// <summary>
        /// Clear the strokes
        /// </summary>
        public void Clear()
        {
            DeleteStrokes();

            InkChanged?.Invoke(this, new EventArgs());
        }
        /// <summary>
        /// Add a collection of ink strokes
        /// </summary>
        /// <param name="strokes">the ink strokes to add</param>
        public void Add(IEnumerable <XInkStroke> strokes)
        {
            AddStrokes(strokes);

            InkChanged?.Invoke(this, new EventArgs());
        }
 /// <summary>
 /// Clear the strokes
 /// </summary>
 public void Dispose()
 {
     Clear();
     InkChanged?.Invoke(this, new EventArgs());
 }
 private void InkPresenter_StrokesCollected(InkPresenter sender, InkStrokesCollectedEventArgs args)
 {
     InkChanged?.Invoke(this, null);
 }