WPF - 使用视图模型数据进行复制/粘贴与拖放时内存不足

发布于 2024-11-29 05:15:57 字数 1849 浏览 0 评论 0原文

我有一个提供拖放以及复制/粘贴功能的TreeView。我扩展了 TreeViewItem 来提供该功能。

拖放效果很好。树绑定到视图模型,并且在 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< 的粘贴方法/code> 如:

    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() 调用时失败,并在从 a 调用时出现 内存不足,无法继续执行程序 消息复制/粘贴操作。我什至将一个空视图模型实例传递到剪贴板,同样出现内存不足的结果。

有一个已知的 VS2010 问题与此类似,解释为 此处。我安装了该修补程序,但内存问题仍然存在。

有什么想法吗?我应该以不同的方式与 Clipboard 进行交互吗?谢谢!

I have a TreeView that provides drag and drop as well as copy/paste functionality. I extended TreeViewItem to provide that functionality.

The drag and drop works fine. The tree is bound to a view model, and the drag is initiated in the TreeViewItem custom class such as:

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

The drop is initiated such as:

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

which calls a paste method that takes in an IDataObject such as:

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

The copy/paste operation is set up as follows. The copy is initiated in the TreeViewItem custom class such as:

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

The paste is initiated such as:

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

calling the same paste method with IDataObject above.

Issue: The same paste method fails at the GetData() call with an Insufficient memory to continue the execution of the program message when called from a copy/paste operation. I've even passed in an empty view model instance to the clipboard, with the same insufficient memory result.

There has been a known VS2010 issue similar to this, explained here. I installed that hotfix, but the memory issue still persists.

Any ideas? Should I be interacting with the Clipboard differently? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梨涡少年 2024-12-06 05:15:57

我过去遇到过这个问题,它与在剪贴板中存储对象有关。我不记得确切的原因,但我需要序列化我的对象并将 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);
    }
}

I had this issue in the past, and it has to do with storing an object in the ClipBoard. I can't remember exactly why, but I needed to serialize my object and store the byte[] in the clipboard instead of the object itself.

The code I used looked something like this:

Writing:

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

Clipboard.SetDataObject(data, true);

Reading:

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)}
    );
}

Serialization Classes

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文