Перетаскивание данных между экземплярами - PullRequest
1 голос
/ 22 мая 2009

Я пытаюсь разрешить моим пользователям перетаскивать определенные строки данных из одного пользовательского элемента управления списком в другой, где второй элемент управления списком находится в другом экземпляре того же приложения.

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 ]

3 голосов
/ 22 мая 2009

Мне удалось воспроизвести вашу первоначальную проблему, но как только я добавил атрибут [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);
        }
    }



}
0 голосов
/ 25 мая 2009

Я думаю, что проблема в том, что вы используете список напрямую для передачи данных. Я попробовал несколько разных способов заставить его выйти из строя и выяснил несколько способов, как он не работает.

Если у вас нет атрибута [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);
    }
}
...