using System.Collections.Generic; using System.Windows; using System.Windows.Media; using Microsoft.Research.DynamicDataDisplay.DataSources; using Microsoft.Research.DynamicDataDisplay.PointMarkers; using Microsoft.Research.DynamicDataDisplay.Common; using System.Windows.Controls; namespace Microsoft.Research.DynamicDataDisplay { public class ElementMarkerPointsGraph : PointsGraphBase { /// List with created but unused markers private readonly List unused = new List(); /// Initializes a new instance of the class. public ElementMarkerPointsGraph() { ManualTranslate = true; // We'll handle translation by ourselves } /// Initializes a new instance of the class. /// The data source. public ElementMarkerPointsGraph(IPointDataSource dataSource) : this() { DataSource = dataSource; } Grid grid; Canvas canvas; protected override void OnPlotterAttached(Plotter plotter) { base.OnPlotterAttached(plotter); grid = new Grid(); canvas = new Canvas { ClipToBounds = true }; grid.Children.Add(canvas); Plotter2D.CentralGrid.Children.Add(grid); } protected override void OnPlotterDetaching(Plotter plotter) { Plotter2D.CentralGrid.Children.Remove(grid); grid = null; canvas = null; base.OnPlotterDetaching(plotter); } protected override void OnDataChanged() { // if (canvas != null) // { // foreach(UIElement child in canvas.Children) // unused.Add(child); // canvas.Children.Clear(); // } // todo почему так? base.OnDataChanged(); } public ElementPointMarker Marker { get { return (ElementPointMarker)GetValue(MarkerProperty); } set { SetValue(MarkerProperty, value); } } public static readonly DependencyProperty MarkerProperty = DependencyProperty.Register( "Marker", typeof(ElementPointMarker), typeof(ElementMarkerPointsGraph), new FrameworkPropertyMetadata { DefaultValue = null, AffectsRender = true } ); protected override void OnRenderCore(DrawingContext dc, RenderState state) { if (Marker == null) return; if (DataSource == null) // No data is specified { if (canvas != null) { foreach (UIElement child in canvas.Children) unused.Add(child); canvas.Children.Clear(); } } else // There is some data { int index = 0; var transform = GetTransform(); using (IPointEnumerator enumerator = DataSource.GetEnumerator(GetContext())) { Point point = new Point(); DataRect bounds = DataRect.Empty; while (enumerator.MoveNext()) { enumerator.GetCurrent(ref point); enumerator.ApplyMappings(Marker); if (index >= canvas.Children.Count) { UIElement newMarker; if (unused.Count > 0) { newMarker = unused[unused.Count - 1]; unused.RemoveAt(unused.Count - 1); } else newMarker = Marker.CreateMarker(); canvas.Children.Add(newMarker); } Marker.SetMarkerProperties(canvas.Children[index]); bounds.Union(point); Point screenPoint = point.DataToScreen(transform); Marker.SetPosition(canvas.Children[index], screenPoint); index++; } Viewport2D.SetContentBounds(this, bounds); while (index < canvas.Children.Count) { unused.Add(canvas.Children[index]); canvas.Children.RemoveAt(index); } } } } } }