private static void element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Graphic element = sender as Graphic; Point position = e.GetPosition(Application.Current.RootVisual); DispatcherTimer timer = element.GetValue(DoubleClickTimerProperty) as DispatcherTimer; if (timer != null) //DblClick { timer.Stop(); Point oldPosition = (Point)element.GetValue(DoubleClickPositionProperty); element.ClearValue(DoubleClickTimerProperty); element.ClearValue(DoubleClickPositionProperty); if (Math.Abs(oldPosition.X - position.X) < 1 && Math.Abs(oldPosition.Y - position.Y) < 1) //mouse didn't move => Valid double click { List <MouseButtonEventHandler> handlers = element.GetValue(DoubleClickHandlersProperty) as List <MouseButtonEventHandler>; if (handlers != null) { foreach (MouseButtonEventHandler handler in handlers) { handler(sender, e); } } return; } } //First click or mouse moved. Start a new timer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(doubleClickInterval) }; timer.Tick += new EventHandler((s, args) => { //DblClick timed out (s as DispatcherTimer).Stop(); element.ClearValue(DoubleClickTimerProperty); //clear timer element.ClearValue(DoubleClickPositionProperty); //clear first click position }); element.SetValue(DoubleClickTimerProperty, timer); element.SetValue(DoubleClickPositionProperty, position); timer.Start(); }
/// <summary> /// Adds a double click event handler. /// </summary> /// <param name="element">The Element to listen for double clicks on.</param> /// <param name="handler">The handler.</param> public static void AddDoubleClick(this Graphic element, MouseButtonEventHandler handler) { element.MouseLeftButtonDown += element_MouseLeftButtonDown; List <MouseButtonEventHandler> handlers; handlers = element.GetValue(DoubleClickHandlersProperty) as List <MouseButtonEventHandler>; if (handlers == null) { handlers = new List <MouseButtonEventHandler>(); element.SetValue(DoubleClickHandlersProperty, handlers); } handlers.Add(handler); }
/// <summary> /// Creates graphic elements and adds them to the graphics layer. /// </summary> /// <param name="layer">Graphics layer that will have features added to it.</param> /// <param name="images">Dictionary of images coming from kmz content or from previous parsing</param> public void CreateGraphics(KmlGraphicsLayer layer, IDictionary<string, ImageBrush> images) { if (layer == null) return; GraphicCollection graphics = new GraphicCollection(); UniqueValueRenderer renderer = new UniqueValueRenderer(); // dummy renderer used to create the legend items (since creation of the swatches from the symbol is not that obvious) // Process each metadata feature in the list foreach (PlacemarkDescriptor feature in placemarks) { KMLStyle style = feature.Symbol.style; if (style.ZipFile != null) { // Look for the image in the zip file if (style.IconImage == null && !String.IsNullOrEmpty(style.IconHref)) { style.IconImage = GetIconImage(style.ZipFile, style.IconHref.ToLower()); } style.ZipFile.Dispose(); style.ZipFile = null; } //Define handlers upfront so we can unhook from them #if SILVERLIGHT EventHandler<RoutedEventArgs> #else EventHandler #endif imageCompleted = null; #if SILVERLIGHT EventHandler<ExceptionRoutedEventArgs> #else EventHandler<ExceptionEventArgs> #endif imageFailed = null; // If the style has an HREF then it is associated with an image if (style.IconImage == null && !String.IsNullOrEmpty(style.IconHref)) { // If the image is already loaded in the image dictionary, use it if (images.ContainsKey(style.IconHref.ToLower())) style.IconImage = images[style.IconHref.ToLower()]; else { // Get the image using the HREF and store the image in the images dictionary so that if // other features reference it, it is cached style.IconImage = GetIconImage(style.IconHref); if (style.IconImage != null && (style.IconImage as ImageBrush).ImageSource != null) { var bi = (style.IconImage as ImageBrush).ImageSource as BitmapImage; if (bi != null) { imageFailed = (s, e) => { var b = s as BitmapImage; #if SILVERLIGHT if (imageCompleted != null) b.ImageOpened -= imageCompleted; if(imageFailed != null) b.ImageFailed -= imageFailed; #else if (imageCompleted != null) b.DownloadCompleted -= imageCompleted; if (imageFailed != null) b.DownloadFailed -= imageFailed; #endif var key = b.GetValue(BitmapImageKeyProperty) as string; layer.Dispatcher.BeginInvoke((Action)delegate { UpdateGraphicsAndRenderer(layer, renderer, key); }); }; #if SILVERLIGHT bi.ImageFailed += imageFailed; #else bi.DownloadFailed += imageFailed; #endif } } images.Add(style.IconHref.ToLower(), style.IconImage); } } // Create a new graphic from the metadata and construct the symbol using polymorphism Graphic g = new Graphic() { Geometry = feature.Geometry, Symbol = feature.Symbol.CreateSymbol(), TimeExtent = feature.TimeExtent }; g.SetValue(FeaturePlacemarkerDescriptorProperty, feature); // Create legend entry string label; string description; GetRendererInfo(feature, style, out label, out description); if (!string.IsNullOrEmpty(label) && !renderer.Infos.Any(info => info.Label == label)) renderer.Infos.Add(new UniqueValueInfo { Label = label, Description = description, Symbol = g.Symbol }); // Adjust and assign picture marker symbol properties if (g.Geometry is ESRI.ArcGIS.Client.Geometry.MapPoint && g.Symbol is KmlPlaceMarkerSymbol) { try { KmlPlaceMarkerSymbol ms = g.Symbol as KmlPlaceMarkerSymbol; // To match sizing of Google Earth, default size of point images is 40x40 ms.Height = 40; ms.Width = 40; ms.Fill = style.IconImage; ms.IconColor = style.IconColor; // Default to half the pixel size (width and height) if symbol offsets are 0 (supported in wpf and sl3) ImageBrush ib = ms.Fill; BitmapImage bi = ib.ImageSource as BitmapImage; #if SILVERLIGHT if (bi.PixelHeight == 0 || bi.PixelWidth == 0) #else if (bi.IsDownloading) #endif { imageCompleted = (s, e) => { var b = s as BitmapImage; #if SILVERLIGHT if (imageCompleted != null) b.ImageOpened -= imageCompleted; if(imageFailed != null) b.ImageFailed -= imageFailed; #else if (imageCompleted != null) b.DownloadCompleted -= imageCompleted; if (imageFailed != null) b.DownloadFailed -= imageFailed; #endif ComputeIconTranslationValues(style, ms, b); }; #if SILVERLIGHT bi.ImageOpened += imageCompleted; #else bi.DownloadCompleted += imageCompleted; #endif } else { ComputeIconTranslationValues(style, ms, bi); } } catch { g.Symbol = PointSymbolDescriptor.GetDefaultSymbol(); ComputeIconTranslationValues(style, g.Symbol as KmlPlaceMarkerSymbol, ((g.Symbol as KmlPlaceMarkerSymbol).Fill as ImageBrush).ImageSource as BitmapImage); var info = renderer.Infos.FirstOrDefault(i => i.Label == label); if (info != null) { info.Symbol = g.Symbol; } } } // Copy attributes values from metadata to graphic foreach (var attribute in feature.Attributes) { g.Attributes.Add(attribute.Key, attribute.Value); } // If the balloontext property has been assigned a value in the style associated with this // graphic feature, then add it to the attributes collection. if (!String.IsNullOrEmpty(style.BalloonText)) { g.Attributes.Add("balloonText", style.BalloonText); } // Add graphic to graphics layer graphics.Add(g); } layer.Graphics = graphics; // keep the renderer for further usage (when QueryLegendInfos is called) layer.RendererBasedOnStyle = renderer; }
/// <summary> /// Creates graphic elements and adds them to the graphics layer. /// </summary> /// <param name="layer">Graphics layer that will have features added to it.</param> /// <param name="images">Dictionary of images coming from kmz content or from previous parsing</param> public void CreateGraphics(KmlGraphicsLayer layer, IDictionary <string, ImageBrush> images) { if (layer == null) { return; } GraphicCollection graphics = new GraphicCollection(); UniqueValueRenderer renderer = new UniqueValueRenderer(); // dummy renderer used to create the legend items (since creation of the swatches from the symbol is not that obvious) // Process each metadata feature in the list foreach (PlacemarkDescriptor feature in placemarks) { KMLStyle style = feature.Symbol.style; if (style.ZipFile != null) { // Look for the image in the zip file if (style.IconImage == null && !String.IsNullOrEmpty(style.IconHref)) { style.IconImage = GetIconImage(style.ZipFile, style.IconHref.ToLower()); } style.ZipFile.Dispose(); style.ZipFile = null; } //Define handlers upfront so we can unhook from them #if SILVERLIGHT EventHandler <RoutedEventArgs> #else EventHandler #endif imageCompleted = null; #if SILVERLIGHT EventHandler <ExceptionRoutedEventArgs> #else EventHandler <ExceptionEventArgs> #endif imageFailed = null; // If the style has an HREF then it is associated with an image if (style.IconImage == null && !String.IsNullOrEmpty(style.IconHref)) { // If the image is already loaded in the image dictionary, use it if (images.ContainsKey(style.IconHref.ToLower())) { style.IconImage = images[style.IconHref.ToLower()]; } else { // Get the image using the HREF and store the image in the images dictionary so that if // other features reference it, it is cached style.IconImage = GetIconImage(style.IconHref); if (style.IconImage != null && (style.IconImage as ImageBrush).ImageSource != null) { var bi = (style.IconImage as ImageBrush).ImageSource as BitmapImage; if (bi != null) { imageFailed = (s, e) => { var b = s as BitmapImage; #if SILVERLIGHT if (imageCompleted != null) { b.ImageOpened -= imageCompleted; } if (imageFailed != null) { b.ImageFailed -= imageFailed; } #else if (imageCompleted != null) { b.DownloadCompleted -= imageCompleted; } if (imageFailed != null) { b.DownloadFailed -= imageFailed; } #endif var key = b.GetValue(BitmapImageKeyProperty) as string; layer.Dispatcher.BeginInvoke((Action) delegate { UpdateGraphicsAndRenderer(layer, renderer, key); }); }; #if SILVERLIGHT bi.ImageFailed += imageFailed; #else bi.DownloadFailed += imageFailed; #endif } } images.Add(style.IconHref.ToLower(), style.IconImage); } } // Create a new graphic from the metadata and construct the symbol using polymorphism Graphic g = new Graphic() { Geometry = feature.Geometry, Symbol = feature.Symbol.CreateSymbol(), TimeExtent = feature.TimeExtent }; g.SetValue(FeaturePlacemarkerDescriptorProperty, feature); // Create legend entry string label; string description; GetRendererInfo(feature, style, out label, out description); if (!string.IsNullOrEmpty(label) && !renderer.Infos.Any(info => info.Label == label)) { renderer.Infos.Add(new UniqueValueInfo { Label = label, Description = description, Symbol = g.Symbol }); } // Adjust and assign picture marker symbol properties if (g.Geometry is ESRI.ArcGIS.Client.Geometry.MapPoint && g.Symbol is KmlPlaceMarkerSymbol) { try { KmlPlaceMarkerSymbol ms = g.Symbol as KmlPlaceMarkerSymbol; // To match sizing of Google Earth, default size of point images is 40x40 ms.Height = 40; ms.Width = 40; ms.Fill = style.IconImage; ms.IconColor = style.IconColor; // Default to half the pixel size (width and height) if symbol offsets are 0 (supported in wpf and sl3) ImageBrush ib = ms.Fill; BitmapImage bi = ib.ImageSource as BitmapImage; #if SILVERLIGHT if (bi.PixelHeight == 0 || bi.PixelWidth == 0) #else if (bi.IsDownloading) #endif { imageCompleted = (s, e) => { var b = s as BitmapImage; #if SILVERLIGHT if (imageCompleted != null) { b.ImageOpened -= imageCompleted; } if (imageFailed != null) { b.ImageFailed -= imageFailed; } #else if (imageCompleted != null) { b.DownloadCompleted -= imageCompleted; } if (imageFailed != null) { b.DownloadFailed -= imageFailed; } #endif ComputeIconTranslationValues(style, ms, b); }; #if SILVERLIGHT bi.ImageOpened += imageCompleted; #else bi.DownloadCompleted += imageCompleted; #endif } else { ComputeIconTranslationValues(style, ms, bi); } } catch { g.Symbol = PointSymbolDescriptor.GetDefaultSymbol(); ComputeIconTranslationValues(style, g.Symbol as KmlPlaceMarkerSymbol, ((g.Symbol as KmlPlaceMarkerSymbol).Fill as ImageBrush).ImageSource as BitmapImage); var info = renderer.Infos.FirstOrDefault(i => i.Label == label); if (info != null) { info.Symbol = g.Symbol; } } } // Copy attributes values from metadata to graphic foreach (var attribute in feature.Attributes) { g.Attributes.Add(attribute.Key, attribute.Value); } // If the balloontext property has been assigned a value in the style associated with this // graphic feature, then add it to the attributes collection. if (!String.IsNullOrEmpty(style.BalloonText)) { g.Attributes.Add("balloonText", style.BalloonText); } // Add graphic to graphics layer graphics.Add(g); } layer.Graphics = graphics; // keep the renderer for further usage (when QueryLegendInfos is called) layer.RendererBasedOnStyle = renderer; }