using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Markup; using System.Windows.Data; using System.Windows; using System.Windows.Threading; using System.ComponentModel; namespace Microsoft.Research.DynamicDataDisplay.Charts.Shapes { /// /// Represents an editor of points' position of ViewportPolyline or ViewportPolygon. /// [ContentProperty("Polyline")] public class PolylineEditor : IPlotterElement { /// /// Initializes a new instance of the class. /// public PolylineEditor() { } private ViewportPolylineBase polyline; /// /// Gets or sets the polyline, to edit points of which. /// /// The polyline. [NotNull] public ViewportPolylineBase Polyline { get { return polyline; } set { if (value == null) throw new ArgumentNullException("Polyline"); if (polyline != value) { polyline = value; var descr = DependencyPropertyDescriptor.FromProperty(ViewportPolylineBase.PointsProperty, typeof(ViewportPolylineBase)); descr.AddValueChanged(polyline, OnPointsReplaced); if (plotter != null) { AddLineToPlotter(false); } } } } bool pointsAdded = false; private void OnPointsReplaced(object sender, EventArgs e) { if (plotter == null) return; if (pointsAdded) return; ViewportPolylineBase line = (ViewportPolylineBase)sender; pointsAdded = true; List draggablePoints = new List(); GetDraggablePoints(draggablePoints); foreach (var point in draggablePoints) { plotter.Children.Add(point); } } private void AddLineToPlotter(bool async) { if (!async) { foreach (var item in GetAllElementsToAdd()) { plotter.Children.Add(item); } } else { plotter.Dispatcher.BeginInvoke(((Action)(() => { AddLineToPlotter(false); })), DispatcherPriority.Send); } } private List GetAllElementsToAdd() { var result = new List(1 + polyline.Points.Count); result.Add(polyline); GetDraggablePoints(result); return result; } private void GetDraggablePoints(List collection) { for (int i = 0; i < polyline.Points.Count; i++) { DraggablePoint point = new DraggablePoint(); point.SetBinding(DraggablePoint.PositionProperty, new Binding { Source = polyline, Path = new PropertyPath("Points[" + i + "]"), Mode = BindingMode.TwoWay }); collection.Add(point); } } #region IPlotterElement Members void IPlotterElement.OnPlotterAttached(Plotter plotter) { this.plotter = (Plotter2D)plotter; if (polyline != null) { AddLineToPlotter(true); } } void IPlotterElement.OnPlotterDetaching(Plotter plotter) { this.plotter = null; } private Plotter2D plotter; /// /// Gets the parent plotter of chart. /// Should be equal to null if item is not connected to any plotter. /// /// The plotter. public Plotter Plotter { get { return plotter; } } #endregion } }