Межпроцессное перетаскивание настраиваемого типа объекта в WinForms C#
-
21-09-2019 - |
Вопрос
Этот вопрос близко к тому, что меня интересует, но не совсем.
У меня есть приложение .NET WinForms, написанное на C#.у меня есть ListView
элемент управления, который отображает массив объектов C#.Я подключил его так, чтобы вы могли перетаскивать эти элементы списка в другую форму в том же приложении, и он правильно передает массив объектов (введите Session
) в обработчик сброса для этой другой формы.
Однако теперь я хочу поддерживать перетаскивание между процессами, когда я запускаю несколько экземпляров своего приложения.Этот появляется что это сработает (например. GetDataPresent
успешно), но в конечном итоге выдает исключение, когда я действительно пытаюсь получить данные - не могу выполнить приведение object[]
к Session[]
.
if (e.Data.GetDataPresent("Fiddler.Session[]"))
{
Session[] oDroppedSessions;
try
{
oDroppedSessions = (Session[])e.Data.GetData("Fiddler.Session[]");
}
catch (Exception eX)
{ // reaches here
}
}
Кто-нибудь знает, если я должен осуществлять ISerializable
для моих объектов, чтобы это работало?Обычно я бы просто попробовал, но реализация ISerializable
для этого класса было бы весьма нетривиально, и я беспокоюсь, что это может привести к странным побочным эффектам.
ОБНОВЛЯТЬ:Реализация ISerializable
не помогает - метод никогда не вызывается.Аналогично, добавив Serializable
атрибут класса вообще не имеет никакого влияния.Есть еще идеи?
Решение
Вы пересекаете границу процесса, ссылки на объекты недопустимы в другом процессе.Класс DataObject поддерживает сериализацию объектов, чтобы перенести их через стену, он использует BinaryFormatter.Итак, да, вам нужно будет применить атрибут [Serializable] к вашему классу и убедиться, что ваши объекты могут правильно де/сериализоваться.
Другие советы
Хорошо, это пример: вместо использования целого набора сеансов попробуйте сделать это индивидуально, вот так...
Session[] oDroppedSessions; try { if (e.Data.GetData("Fiddler.Session[]") != null){ object[] objs = e.Data.GetData("Fiddler.Session[]"); if (objs != null && objs.Length > 1){ oDroppedSessions = new Session[objs.Length]; int nIndex = 0; foreach(object obj in objs){ if (obj is Session){ oDroppedSessions[nIndex] = (Session)obj; nIndex++; } } } } } catch (Exception eX) { // reaches here }
Стоит попробовать, кроме выстрела себе в ногу, поскольку я не до конца понимаю часть сеанса, попробуйте...
Надеюсь, это поможет, с уважением, Том.
Вы можете использовать «as» для приведения, которое позволит избежать исключения («as» вернет «null» без создания исключения в случае сбоя приведения) – но я не думаю, что это решит вашу проблему (это просто позволит избежать фактического исключение), поскольку я согласен, что вам, скорее всего, придется сделать свой класс сериализуемым.Вы можете проверить свою гипотезу, закомментировав те поля, в которых ее будет труднее заставить работать — просто сейчас, чтобы проверить ее.