Richie 的个人资料The Sandpit - "We hack s...日志列表 工具 帮助
3月16日

How to create a drop target for layers from ArcMap?

Drag and drop is a convenient and intuitive method of exchanging data between windows (and applications).  ESRI applications like ArcCatalog and ArcMap have drop and drop capabilities, for example, you can drag layer into the Buffer geoprocessing tool window (see below). 

Using the sample code below you can add this capability to your .NET application, that is, you can make your window/control a drop target for layers dragged from the ArcMap table of contents.  This code can be used in window hosted by an ESRI application such as an ArcMap dockable widnow or as a standalone application.

To enable this feature a utility class called "EsriDataObject" was developed to deserialize the dropped object from ArcMap to a collection of ESRI layers.  The source code to "EsriDataObject" is provided in the second code sample below.

The first code sample demonstrates how to use "EsriDataObject" in a .NET form.  The code shows a Form called "form1" with a TextBox called "textBox1".  The TextBox will display the name(s) of layers that are dropped from ArcMap

Sample 1: How to use "EsriDataObject" in a .NET Form.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using ESRI.ArcGIS.Carto;

namespace MyNamespace {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
            this.textBox1.AllowDrop = true;
            this.textBox1.DragEnter += new DragEventHandler(this.textBox1_DragEnter);
            this.textBox1.DragOver += new DragEventHandler(this.textBox1_DragOver);
            this.textBox1.DragDrop += new DragEventHandler(this.textBox1_DragDrop);
        }
        private void textBox1_DragEnter(object sender, DragEventArgs e) {
            e.Effect = EsriDataObject.IsValid(e.Data) ? DragDropEffects.All : DragDropEffects.None;
        }
        private void textBox1_DragOver(object sender, DragEventArgs e) {
            e.Effect = EsriDataObject.IsValid(e.Data) ? DragDropEffects.All : DragDropEffects.None;
        }
        private void textBox1_DragDrop(object sender, DragEventArgs e) {
            EsriDataObject esriDataObject = EsriDataObject.ConvertToEsriDataObject(e.Data);
            foreach (ILayer layer in esriDataObject.LayerCollection) {
                this.textBox1.Text += layer.Name + " ";
            }
        }
    }
}

Sample 2: Source code to "EsriDataObject".

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;

using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.esriSystem;

namespace MyNamespace {
    public class EsriDataObject {
        private const string DATAOBJECT_ESRILAYERS = "ESRI Layers";
        private const string INTERFACE_ILAYER = "{34C20002-4D3C-11D0-92D8-00805F7C28B0}";
        private const string INTERFACE_ITABLEPROPERTY = "{4657D951-5FFB-11D3-9F6C-00C04F6BC886}";
        private readonly List<ILayer> m_layerCollection = null;
        private readonly List<ITableProperty> m_tablePropertyCollection = null;
        //
        // CONSTRUCTOR
        //
        public EsriDataObject() {
            this.m_layerCollection = new List<ILayer>();
            this.m_tablePropertyCollection = new List<ITableProperty>();
        }
        //
        // PROPERTIES
        //
        public List<ILayer> LayerCollection {
            get { return this.m_layerCollection; }
        }
        public List<ITableProperty> TablePropertyCollection {
            get { return this.m_tablePropertyCollection; }
        }
        //
        // STATIC METHODS
        //
        public static bool IsValid(IDataObject dataObject) {
            return dataObject.GetDataPresent(DATAOBJECT_ESRILAYERS);
        }
        public static EsriDataObject ConvertToEsriDataObject(IDataObject dataObject) {
            //
            EsriDataObject esriDataObject = new EsriDataObject();

            // Exit if dropped object is invalid
            if (EsriDataObject.IsValid(dataObject)) {
                // Get Byte Array from DataObject
                object esriLayers = dataObject.GetData(DATAOBJECT_ESRILAYERS);
                MemoryStream memoryStream = (MemoryStream)esriLayers;
                byte[] bytes = memoryStream.ToArray();

                // Load Byte Array into a Stream (ESRI Wrapper of IStream)
                IMemoryBlobStreamVariant memoryBlobStreamVariant = new MemoryBlobStreamClass();
                memoryBlobStreamVariant.ImportFromVariant(bytes);
                IMemoryBlobStream2 memoryBlobStream = (IMemoryBlobStream2)memoryBlobStreamVariant;
                IStream stream = (IStream)memoryBlobStream;

                // Load Stream into an ESRI ObjectStream
                IObjectStream objectStream = new ObjectStreamClass();
                objectStream.Stream = stream;

                // Get Number of Layers in Dropped Object
                byte pv;
                uint cb = sizeof(int);
                uint pcbRead;
                objectStream.RemoteRead(out pv, cb, out pcbRead);
                int count = Convert.ToInt32(pv);

                // Define Guids
                Guid guidLayer = new Guid(INTERFACE_ILAYER);
                Guid guidTable = new Guid(INTERFACE_ITABLEPROPERTY);

                // Get Dropped Layers
                for (int i = 0; i < count; i++) {
                    object o = objectStream.LoadObject(ref guidLayer, null);
                    ILayer layer = (ILayer)o;
                    esriDataObject.LayerCollection.Add(layer);
                }

                // Get Dropped TableProperties
                for (int i = 0; i < count; i++) {
                    object o = objectStream.LoadObject(ref guidTable, null);
                    if (o == null) { continue; }
                    ITableProperty tableProperty = (ITableProperty)o;
                    esriDataObject.TablePropertyCollection.Add(tableProperty);
                }
            }

            return esriDataObject;
        }
    }
}

评论 (4)

请稍候...
很抱歉,您输入的评论太长。请缩短您的评论。
您没有输入任何内容,请重试。
很抱歉,我们当前无法添加您的评论。请稍后重试。
若要添加评论,需要您的家长授予您相应权限。请求权限
您的家长禁用了评论功能。
很抱歉,我们当前无法删除您的评论。请稍后重试。
您已超过了一天之内允许提供的评论数上限。请在 24 小时后重试。
因为我们的系统表明您可能在向其他用户提供垃圾评论,您的帐户已禁用了评论功能。如果您认为我们错误地禁用了您的帐户,请联系 Windows Live 支持部门
完成下面的安全检查,您提供评论的过程才能完成。
您在安全检查中键入的字符必须与图片或音频中的字符一致。
Carmichael​Richie 在此页禁用了评论功能。
Hi Leo,
 
Dragging and dropping objects from ArcCatalog is a lot easier than ArcMap.
 
In ArcMap, a dragged object is packaged as an "ESRI Layer" object in the DataObject.  The code above describes how to unpack an "ESRI Layer" object.
 
In ArcCatalog, a dragged object is packaged as an "ESRI Names" object in the DataObject.  Fortunately, there are ArcObjects available to pack and unpack this object.
 
To create an "ESRI Names" object use the following:
 
To unpackage an "ESRI Names" object use:
 
Lastly, here is an online example showing how to unpackage an "ESRI Names" object:
 
Hope this helps and thanks for your feedback.
3 月 4 日
leo发表:
Excellent code sample.  Used it as is without hitch.  Works great! Using your logic for Mx I tried modifying for Gx, but cannot find a way to access ESRI's Gx dataobject blob/binary stream.  I tried "ESRI Names".  Do you have code for Gx?  Interested in dragging & dropping Gx FeatureLayers shapefiles, personal geodatabase, as well as ArcSDE layer.

Thanks
2 月 26 日
Richie...That was great sample thanks for sharing.
I am trying to implement drag and drop functionality to get the database connection (path and file name) but having difficulty to get started. I already implemented IGxObject, IGxDialog for getting the path and file name once the user clicks.
I would appreciate if you could give me a jump start.
Here is my scenario: User can select a personal geodatabase and drag it on to the textbox control on windows form and i want to show fullpath and filename in the text box.
Thanks
12 月 28 日
匿名 的图片
Mike Juniper 发表:
Thanks for the sample, that's really great.  I wish you'd posted it six months ago when I was trying to figure this out!
3 月 19 日

引用通告

引用此项的网络日志