WinForms Interop, Перетаскивание от WinForms-> WPF

Соглашения о присвоении имен предлагают преимущество сообщения Вам что-то об объекте перед использованием его. Соглашения о присвоении имен широко много лет использовались, идя полностью назад в настойчивость Фортрана, что целочисленные значения были ограничены (если я помню правильно) к именам переменной как "i" и "j".

нотация Hungariation взяла соглашения о присвоении имен к совершенно новому ужасному уровню tha, описал тип переменной, было ли это указателем и т.д. Многие из нас, кто был представлен большому количеству кода с Венгерской записью, разработали нервные подергивания и словесные задержки.

имена интерфейса Добавления префикса с я относительно низкое влияние, безопасный способ определить тот объект.

17
задан Drew Noakes 31 July 2009 в 16:21
поделиться

3 ответа

@Pedery & jmayor: Спасибо за предложения, ребята! (см. мои выводы ниже)

После нескольких экспериментов, проб и ошибок, а также небольшого количества «отражений» мне удалось точно выяснить, почему я получаю загадочное сообщение об ошибке «Ошибка HRESULT E_FAIL возвращена. от вызова COM-компонента ».

Это произошло из-за того, что при перетаскивании данных WPF <-> Winforms в том же приложении данные должны быть сериализуемыми!

I ' Я проверил, насколько сложно будет преобразовать все наши классы в "сериализуемые", и это было бы настоящей проблемой по нескольким причинам ... во-первых, нам нужно было бы практически сделать все классы сериализуемыми, а во-вторых, некоторые этих классов есть ссылки на Controls! И элементы управления не сериализуемы. Таким образом, потребовался бы серьезный рефакторинг.

Итак ... поскольку мы хотели передать любой объект любого класса для перетаскивания из / в WPF внутри одного и того же приложения, я решил создать класс-оболочку с атрибутом Serializable и реализовать ISerializable. У меня будет 1 конструктор с 1 параметром типа «объект», который будет фактическими данными перетаскивания. Эта оболочка при сериализации / десериализации будет сериализовать не сам объект ... а, скорее, IntPtr для объекта (что мы можем сделать, поскольку нам нужна только эта функциональность внутри нашего приложения, содержащего только 1 экземпляр). См. Пример кода ниже:

[Serializable]
public class DataContainer : ISerializable
{
public object Data { get; set; }

public DataContainer(object data)
{
    Data = data;
}

// Deserialization constructor
protected DataContainer(SerializationInfo info, StreamingContext context)
{
    IntPtr address = (IntPtr)info.GetValue("dataAddress", typeof(IntPtr));
    GCHandle handle = GCHandle.FromIntPtr(address);
    Data = handle.Target;
    handle.Free();
}

#region ISerializable Members

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
    GCHandle handle = GCHandle.Alloc(Data);
    IntPtr address = GCHandle.ToIntPtr(handle);
    info.AddValue("dataAddress", address);
}

#endregion
}

Чтобы сохранить функциональность IDataObject, я создал следующую оболочку DataObject:

public class DataObject : IDataObject
{
System.Collections.Hashtable _Data = new System.Collections.Hashtable();

public DataObject() { }

public DataObject(object data)
{
    SetData(data);
}

public DataObject(string format, object data)
{
    SetData(format, data);
}

#region IDataObject Members

public object GetData(Type format)
{
    return _Data[format.FullName];
}

public bool GetDataPresent(Type format)
{
    return _Data.ContainsKey(format.FullName);
}

public string[] GetFormats()
{
    string[] strArray = new string[_Data.Keys.Count];
    _Data.Keys.CopyTo(strArray, 0);
    return strArray;
}

public string[] GetFormats(bool autoConvert)
{
    return GetFormats();
}

private void SetData(object data, string format)
{
    object obj = new DataContainer(data);

    if (string.IsNullOrEmpty(format))
    {
        // Create a dummy DataObject object to retrieve all possible formats.
        // Ex.: For a System.String type, GetFormats returns 3 formats:
        // "System.String", "UnicodeText" and "Text"
        System.Windows.Forms.DataObject dataObject = new System.Windows.Forms.DataObject(data);
        foreach (string fmt in dataObject.GetFormats())
        {
            _Data[fmt] = obj;
        }
    }
    else
    {
        _Data[format] = obj;
    }
}

public void SetData(object data)
{
    SetData(data, null);
}

#endregion
}

И мы используем вышеуказанные классы следующим образом:

myControl.DoDragDrop(new MyNamespace.DataObject(myNonSerializableObject));

// in the drop event for example
e.Data.GetData(typeof(myNonSerializableClass));

Я знаю, я знаю ... это не очень красиво . .. но он делает то, что мы хотели. Мы также создали вспомогательный класс перетаскивания, который маскирует создание DataObject и имеет шаблонные функции GetData для извлечения данных без каких-либо преобразований ... примерно так:

myNonSerializableClass newObj = DragDropHelper.GetData<myNonSerializableClass>(e.Data);

Так что еще раз спасибо за ответы! Ребята, вы дали мне хорошие идеи, где искать возможные решения!

-Oli

16
ответ дан 30 November 2019 в 13:28
поделиться

Некоторое время назад у меня была «похожая» проблема, поэтому я могу хотя бы рассказать вам то, что обнаружил.

Похоже .Net прибегает к удаленному взаимодействию OLE, когда выполняются операции перетаскивания. выполняется в простейших случаях. По какой-то причине GetDataPresent в этих случаях будет успешным, а GetData - нет. Кроме того, это загадочно из-за того, что существует несколько версий IDataObject в структуре .Net.

Windows Forms по умолчанию использует System.Windows.Forms.IDataObject. Однако в вашем случае вы можете попробовать дать System.Runtime.InteropServices.ComTypes.IDataObject вместо этого выстрел. Вы также можете посмотреть мое обсуждение здесь .

Надеюсь, это поможет.

5
ответ дан 30 November 2019 в 13:28
поделиться

Может, все наоборот. PreviewDragEnter должен быть связан с WPFTextBox. Также обратите внимание на класс DragEventArgs. Один находится в System.Windows.Form (версия Windows Form), а другой - в System.Windows (для версии WPF).

0
ответ дан 30 November 2019 в 13:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: