在实例之间拖放数据

时间:2009-05-22 10:05:43

标签: c# winforms .net-3.5 drag-and-drop

我正在尝试允许我的用户将某些数据行从一个自定义列表控件拖放到另一个自定义列表控件,其中第二个列表控件位于同一应用程序的另一个实例中。

DoDragDrop(parameterTypedListView.SelectedObjects, DragDropEffects.Copy);

其中parameterTypedListView.SelectedObjects是通用IList,其中T是仅包含值类型为字段/属性的自定义类。

在OnDragDrop事件中,我尝试提取此数据,但只获取一个似乎从System.__ComObject继承的System.MarshalByRefObject ...对象。

简而言之:如何以我可以实际使用的面向对象格式提取数据?

编辑:将我的自定义类设置为可序列化无论如何都没有明显的效果。我可以枚举__ComObject:

foreach (var dataObject in (IEnumerable) e.Data.GetData("System.Collections.ArrayList"))
{
    // this actually enumerates the correct number of times, i.e. as many times as there are items in the list.
}

但是每个dataObject本身都是一个System .__ ComObject,我无法将它转换为任何有用的东西。

2 个答案:

答案 0 :(得分:3)

我能够复制你的初始问题,但是一旦我将[Serializable]属性添加到数组列表中的类,我就能够看到对象是正确的类型。

这是一些示例代码,显示了一个小工作示例。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form1_DragDrop);
        this.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form1_DragEnter);
    }

    [Serializable]
    class DragClass
    {
        public string Prop1 { get; set; }
        public int Prop2 { get; set; }
    }

    private void label1_MouseDown(object sender, MouseEventArgs e)
    {
        System.Collections.ArrayList aDragClasses = new System.Collections.ArrayList();
        aDragClasses.Add(new DragClass() { Prop1 = "Test1", Prop2 = 2 });
        aDragClasses.Add(new DragClass() { Prop1 = "Test2", Prop2 = 3 });
        aDragClasses.Add(new DragClass() { Prop1 = "Test3", Prop2 = 4 });

        DoDragDrop(aDragClasses, DragDropEffects.Copy);
    }

    private void Form1_DragEnter(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Copy;
    }

    private void Form1_DragDrop(object sender, DragEventArgs e)
    {
        foreach (var aData in (System.Collections.IEnumerable)e.Data.GetData(typeof(System.Collections.ArrayList)))
        {
          System.Diagnostics.Debug.WriteLine(((DragClass)aData).Prop1);
        }
    }



}

答案 1 :(得分:0)

我认为问题在于您直接使用列表来传递数据。我尝试了几种不同的方法让它失败,并想出了一些不起作用的方法。

如果您的自定义类上没有[Serializable]属性,它将无法正常工作,因为这是在进程之间封送类的方式。另外,如果我直接使用List传递数据,我会得到一个空引用异常。

如果你使用一个简单的传输类来传递数据(并且所有类型都是可序列化的)那么一切都适合我。

[Serializable]
class Test
{
    public string Name { get; set; }
    public string Description { get; set; }
}

[Serializable]
class Transport
{
    public Transport()
    {
        this.Items = new List<Test>();
    }
    public IList<Test> Items { get; private set; }
}

然后我可以做到这一点没有问题,它可以跨实例工作......

private void Form1_DragDrop(object sender, DragEventArgs e)
{
    foreach (var item in ((Transport)e.Data.GetData(typeof(Transport))).Items)
    {
        System.Diagnostics.Debug.WriteLine(item.Name + " " + item.Description);
    }
}