“Our requirement is to show a open hand cursor while hovering over XamMap and while panning a XamMap, show a dragging hand cursor. There has been quite a few blog posts on how to create custom cursors in Silverlight, but We felt some of them were very limited or not very re-useable, or required you to put the cursor in the layout and put restrictions on your layout (like for instance requiring you to use a Canvas as parent for your cursor). One of the approach we used out here: You “disable” the cursor on your XamMap by setting xamMap.Cursor = Cursors.None. Next you move a custom UIElement(open hand image) around on top of your layout which represents your custom cursor. But with this approach we are facing two main problems: 1. Since we are using a Popup to hold drag cursor image, Sometimes when the popup opens it stops dragging completely. 2. While zooming a XamMap,it stops zooming intermittently. This is because we are opening this popup on "xamMap_WindowRectChanged" event and this event is called while panning as well as zooming.”
Hi bharath,
Unfortunately I don't think there is an easy way to achieve this behaiour in Silverlight. I have tried another approach - to use SymbolElement for the mouse cursor. The following sample uses 2 MapLayers, one for the open hand and another fot the dragging hand cursor. A single SymbolElement is added in each layer to represent cursor position. On XamMap's MapMouseMove the SymbolElement's SymbolOrigin value is updated. There are a couple of issues although. XamMap's elements cannot be hovered and XamMap's WindowAnimationMode is set to MapWindowAnimationMode.None.
XAML:
<Maps:XamMap x:Name="xamMap" Width="800" Height="600"> <Maps:MapNavigationPane igControls:XamDock.Edge="InsideRight" /> <Maps:XamMap.Layers> <Maps:MapLayer Imported="MapLayer_Imported"> <Maps:MapLayer.Reader> <Maps:ShapeFileReader Uri="Shapefiles/world/world" DataMapping="Caption=CNTRY_NAME"/> </Maps:MapLayer.Reader> </Maps:MapLayer>
<Maps:MapLayer> <Maps:MapLayer.ValueTemplate> <DataTemplate> <Image Source="hand1.png"> </Image> </DataTemplate> </Maps:MapLayer.ValueTemplate> </Maps:MapLayer>
<Maps:MapLayer> <Maps:MapLayer.ValueTemplate> <DataTemplate> <Image Source="hand2.png"> </Image> </DataTemplate> </Maps:MapLayer.ValueTemplate> </Maps:MapLayer> </Maps:XamMap.Layers></Maps:XamMap>
Code behind:
public partial class MouseCursorTest : Page{ private SymbolElement _hand1; private SymbolElement _hand2; private SymbolElement _currentHand; private double _previousWindowZoom; private Point _position;
public MouseCursorTest() { InitializeComponent();
xamMap.WindowAnimationMode = MapWindowAnimationMode.None;
xamMap.MapMouseMove += (sender, e) => { if (_currentHand != null) { _position = e.Position;
_currentHand.SymbolOrigin = xamMap.Viewport.RootCanvas.RenderTransform.Inverse.Transform(_position); } };
xamMap.WindowRectChanged += (sender, e) => { if (_previousWindowZoom == xamMap.WindowZoom) { xamMap.Layers[1].IsVisible = false; xamMap.Layers[2].IsVisible = true;
_currentHand = _hand2; } else { xamMap.Layers[1].IsVisible = true; xamMap.Layers[2].IsVisible = false;
_currentHand = _hand1; _previousWindowZoom = xamMap.WindowZoom;
xamMap.MapMouseLeftButtonUp += (sender, e) => { xamMap.Layers[1].IsVisible = true; xamMap.Layers[2].IsVisible = false;
_currentHand = _hand1; }; }
private void MapLayer_Imported(object sender, MapLayerImportEventArgs e) { if (e.Action == MapLayerImportAction.End) { var origin = new Point(xamMap.Layers[0].WorldRect.Left + xamMap.Layers[0].WorldRect.Width / 2.0, xamMap.Layers[0].WorldRect.Top + xamMap.Layers[0].WorldRect.Height / 2.0);
_hand1 = new SymbolElement { SymbolOrigin = origin, SymbolType = MapSymbolType.None, IsClickable = false, IsSensitive = false }; _hand2 = new SymbolElement { SymbolOrigin = origin, SymbolType = MapSymbolType.None, IsClickable = false, IsSensitive = false };
xamMap.Layers[1].LayerName = "Layer 1"; xamMap.Layers[1].WorldRect = xamMap.Layers[0].WorldRect; xamMap.Layers[1].Elements.Add(_hand1); xamMap.Layers[1].IsVisible = false;
xamMap.Layers[2].LayerName = "Layer 2"; xamMap.Layers[2].WorldRect = xamMap.Layers[0].WorldRect; xamMap.Layers[2].Elements.Add(_hand2); xamMap.Layers[2].IsVisible = false;
_previousWindowZoom = xamMap.WindowZoom; } }}
Regards,
Ivan Kotev
I tried with this approach but its not updating position of _currentHand on panning and also not updating on Mousemove.