【问题标题】:Drag'n'drop data between instances在实例之间拖放数据
【发布时间】:2009-05-22 10:05:43
【问题描述】:

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

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 个不同的实例中运行两次?
  • @Konstantinos,是的,同一应用程序的多个实例。

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


【解决方案1】:

我能够复制您最初的问题,但是只要我将 [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);
        }
    }



}

【讨论】:

    【解决方案2】:

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

    如果您的自定义类没有 [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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-15
      • 2018-12-21
      • 1970-01-01
      • 2018-04-15
      相关资源
      最近更新 更多