I have a ListBox in a Dockpane from where I want to Drag/Drop items onto a Map. When starting the Drag the StartDrag method is triggered. However, neither OnDragOver or OnDrop is ever triggered thereafter.
My XAML file has a reference to the DragDrop namespace and the ListBox is set as drag source
xmlns:dragDrop="clr-namespace:ArcGIS.Desktop.Framework.DragDrop;assembly=ArcGIS.Desktop.Framework"
<ListBox x:Name="DataLayerList" ItemsSource="{Binding LayersFiltered, Mode=TwoWay}" dragDrop:DragDrop.IsDragSource="True" dragDrop:DragDrop.DragHandler="{Binding}"/>
My ViewModel implements IDragSource and here is my Drag&Drop part. Where OnDragOver and OnDrop is never triggered when I pull an item from the ListBox onto a Map.
private List<string> _dragLayerGuids;
public void StartDrag(DragInfo dragInfo)
{
IEnumerable sourceItems = dragInfo.SourceItems;
if (sourceItems == null)
{
return;
}
_dragLayerGuids = new List<string>();
foreach (ThemeLayer layer in sourceItems)
{
_dragLayerGuids.Add(layer.Id);
}
}
public override void OnDragOver(DropInfo dropInfo)
{
dropInfo.Effects = DragDropEffects.All;
}
public override void OnDrop(DropInfo dropInfo)
{
if (_dragLayerGuids != null)
{
AddService(_dragLayerGuids);
}
}
What am I missing to make this work?
Hi,
Have you tried Esri community sample Drag And Drop . There is a part where FGDB featureclass drags to map.
Yes, I worked with both examples, the one you mentioned and the one for the Excel file drop.
Hi,
Your ThemeLayer must have method:
public virtual ItemInfoValue GetItemInfoValue()
Your StartDrag method must be like this:
List<ClipboardItem> clip_items = new List<ClipboardItem>();
foreach (ThemeLayer layer in sourceItems)
{
clip_items.Add(new ClipboardItem()
{
ItemInfoValue = layer.GetItemInfoValue()
});
}
dragInfo.Data = clip_items;
dragInfo.Effects = DragDropEffects.Copy;
The ThemeLayer class contains already the GetItemInfoValue() method, but
public virtual ItemInfoValue GetItemInfoValue()
{
string uri = Id;
Item portalItem = ItemFactory.Instance.Create(uri, ItemFactory.ItemType.PortalItem);
return new ItemInfoValue()
{
name = portalItem?.Name,
title = portalItem?.Name,
catalogPath = portalItem?.Path,
type = portalItem?.Type,
typeID = portalItem?.TypeID,
isContainer = "false" // is that correct?
};
}
returned always null, as long as I was giving the url to the portal item, instead of simply handing the item id over.
However, now my issue is that the items path value is not pointing at the service itself but at a directory, via the Rest api: "https://portal.com/fed/rest/services/folder/service_name/FeatureServer".
As I see it the actual Feature Service would be found at : "https://portal.com/fed/rest/services/folder/service_name/FeatureServer/0". Now, that one I cannot access, since:
ArcGIS REST Framework |
Home |
string curService = $"https://portal.com/portal/home/item.html?id={guid}"
LayerFactory.Instance.CreateLayer(new Uri(curService, UriKind.Absolute), activeMapView.Map, 0);
and that's what I planned to have in the OnDrop() method. But, I never reach the method, because the end of the StartDrag() method leads to a warning-messagebox: Add data - Failed to add data: https://portal.com/fed/rest/services/folder/service_name/FeatureServer
I would rather have the OnDrop() method doing the job of adding the items to the map. Currently it seems that the StartDrag() method is doing everything, which does not make sense, since it is immediately activated when dragging something, without even knowing where it is dragged to.
Does that make sense?