WPF - недостаточно памяти при копировании / вставке или перетаскивании с просмотром данных модели - PullRequest
2 голосов
/ 09 августа 2011

У меня есть TreeView, который обеспечивает перетаскивание, а также функцию копирования / вставки. Я расширил TreeViewItem, чтобы обеспечить эту функциональность.

drag & drop работает отлично. Дерево связывается с моделью представления, и перетаскивание инициируется в пользовательском классе TreeViewItem, таком как:

    protected override void OnMouseMove(MouseEventArgs e)
    {
        // ...
        if (canDrag)
        {
            DragDrop.DoDragDrop(this, DataContext, DragDropEffects.Copy);
            e.Handled = true;
        }
    }

Дроп инициируется, например:

    protected override void OnDrop(DragEventArgs e)
    {
        // ...
        Paste(e.Data);
        e.Handled = true;
    }

, который вызывает метод вставки, который принимает IDataObject, такой как:

    protected void Paste(IDataObject data)
    {
        // ...
        if (data.GetDataPresent(typeof(FooViewModel)) == true)
        {
            // process Foo drop
            copiedFoo = data.GetData(typeof(FooViewModel)) as FooViewModel;
            // ...
        }
    }

Операция копировать / вставить настроена следующим образом. Копирование инициируется в пользовательском классе TreeViewItem, например:

    void CopyExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        Clipboard.Clear();
        Clipboard.SetData(DataContext.GetType().ToString(), DataContext);
    }

Паста инициируется, например:

    void PasteExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        Paste(Clipboard.GetDataObject());
    }

вызов того же метода вставки с IDataObject выше.

Проблема: Сбой того же метода вставки при вызове GetData() с Недостаточно памяти для продолжения выполнения программного сообщения при вызове из операции копирования / вставки. Я даже передал пустой экземпляр модели представления в буфер обмена с таким же недостаточным результатом памяти.

Была известная проблема VS2010, подобная этой, объясненная здесь . Я установил это исправление, но проблема с памятью все еще сохраняется.

Есть идеи? Должен ли я взаимодействовать с Clipboard по-другому? Спасибо!

1 Ответ

3 голосов
/ 09 августа 2011

У меня была эта проблема в прошлом, и она связана с хранением объекта в ClipBoard.Я точно не помню почему, но мне нужно было сериализовать мой объект и сохранить byte[] в буфере обмена вместо самого объекта.

Код, который я использовал, выглядел примерно так:

Запись:

byte[] data = SerializationHelpers.SerializeToBinary<TreeNodeBase>(
    selectedTreeNode, 
    new Type[] { typeof(TreeNodeA), typeof(TreeNodeB),typeof(TreeNodeC)}
);

Clipboard.SetDataObject(data, true);

Запись:

IDataObject data = Clipboard.GetDataObject();
if (data.GetDataPresent(typeof(byte[])))
{
    MyClass obj = SerializationHelpers.DeserializeFromBinary<TreeNodeBase>(
        (byte[])data.GetData(typeof(byte[])), 
        new Type[] {typeof(TreeNodeA), typeof(TreeNodeB),typeof(TreeNodeC)}
    );
}

Классы сериализации

public static byte[] SerializeToBinary<T>(T obj, Type[] extraTypes)
{
    if (obj == null)
        return null;

    using (MemoryStream ms = new MemoryStream())
    {
        DataContractSerializer dcs = new DataContractSerializer(typeof(T), extraTypes);
        dcs.WriteObject(ms, obj);
        return ms.ToArray();
    }
}

public static T DeserializeFromBinary<T>(byte[] data, Type[] extraTypes)
{
    if (data.Length == 0)
        return default(T);

    using (MemoryStream ms = new MemoryStream())
    {
        ms.Write(data, 0, data.Length);
        ms.Seek(0, 0);

        DataContractSerializer dcs = new DataContractSerializer(typeof(T), extraTypes);
        return (T)dcs.ReadObject(ms);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...