Closed mennowo closed 3 years ago
Meanwhile, I managed doing this. For future reference, here is a small class for this purpose:
public class DragPin : Pushpin
{
private bool _isDragging = false;
public DragPin() : base()
{
MouseLeftButtonDown += OnMouseLeftButtonDown;
MouseRightButtonDown += OnMouseRightButtonDown;
}
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (sender is DragPin p)
{
var map = p.GetVisualAncestor<Map>();
if (map != null)
{
map.MouseUp += ParentMap_MouseLeftButtonUp;
map.PreviewMouseMove += ParentMap_MouseMove;
_isDragging = true;
}
}
}
private void ParentMap_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
// Left Mouse Button released, stop dragging the Pushpin
if (sender is Map m)
{
m.MouseUp -= ParentMap_MouseLeftButtonUp;
m.MouseMove -= ParentMap_MouseMove;
}
_isDragging = false;
}
void ParentMap_MouseMove(object sender, MouseEventArgs e)
{
if (sender is Map m)
{
// Check if the user is currently dragging the Pushpin
if (_isDragging)
{
// If so, the Move the Pushpin to where the Mouse is.
var mouseMapPosition = e.GetPosition(m);
var mouseGeocode = m.ViewToLocation(mouseMapPosition);
Location = mouseGeocode;
e.Handled = true;
}
}
}
}
This class uses an extension method VisualTreeExtensions.GetVisualAncestor
, which can be easily found online, for example here.
To use the class, use it in the Template for a given set of MapItems. For example:
<Style x:Key="DraggablePinStyle" TargetType="map:MapItem" d:DataContext="{d:DesignInstance viewModels:DragPinViewModel}">
<Setter Property="map:MapPanel.Location" Value="{Binding Location,Mode=TwoWay}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="map:MapItem">
<views:DragPin map:MapPanel.Location="{Binding Path=Location,Mode=TwoWay}" Style="{StaticResource DragPinStyle}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Here DragPinStyle
obiously is a style that defines what the pin will look like on the map. Now we can easily databind a set of items to be displayed - and dragged - on the map:
<map:MapItemsControl ItemsSource="{Binding Path=DraggablePins}"
ItemContainerStyle="{StaticResource DraggablePinStyle}" />
It may not be the most elegant way, but this allows databinding Locations for items that can be dragged by the user.
Hello, would it be do-able to enable the user to drag items on the map, and monitor changes in locations via databinding? I am having a hard time getting my head around what template/style I should use for this (Thumb?) and how to databind Location from the map to the ViewModel. Sorry to be using an issue as for a question like this, feel free to just close this. Any kind of pointer would be welcome. Greets, Menno