用户控件上的 WPF 剪切、复制、粘贴功能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17814530/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:16:16  来源:igfitidea点击:

WPF cut, copy, paste functionality on a user control

c#wpfuser-controls

提问by kev3kev3

I have a canvas on which you can add UserControls (consists of images and textboxes)

我有一个画布,您可以在其上添加 UserControls(由图像和文本框组成)

Im trying to implement cut, copy, paste functionality on these UserControls, so the context menu is attatched to a UserControl which deals with images for example. A user right clicks here and from the context menu picks copy for instance how would I then go about implementing so they can paste this on to the canvas.

我试图在这些 UserControl 上实现剪切、复制、粘贴功能,因此上下文菜单附加到处理图像的 UserControl 上。用户右键单击此处并从上下文菜单中选择副本,例如我将如何实施以便他们可以将其粘贴到画布上。

Can anyone point me in the right direction...

谁能指出我正确的方向...

回答by nmclean

This can be done with RoutedCommands. A full overview is at MSDN: Commanding Overview

这可以通过 RoutedCommands 来完成。完整概述位于 MSDN:命令概述

The short version is this: when a command source(i.e. a menu item) wants to execute a command, an event is raised. That event is handled by the nearest command binding. Cut/copy/paste commands are already included with WPF, and certain elements (namely, text boxes) already include command bindings for them.

简短的版本是这样的:当命令源(即菜单项)想要执行命令时,会引发一个事件。该事件由最近的命令绑定处理。剪切/复制/粘贴命令已经包含在 WPF 中,并且某些元素(即文本框)已经包含它们的命令绑定。

You can define a menu item like this:

您可以像这样定义菜单项:

<MenuItem Header="Copy" Command="ApplicationCommands.Copy" />

And add a command binding to the UserControl like this:

并向 UserControl 添加命令绑定,如下所示:

<UserControl.CommandBindings>
    <CommandBinding Command="ApplicationCommands.Copy"
                    Executed="Copy_Executed" />
</UserControl.CommandBindings>

And define the Copy_Executedmethod with the ExecutedRoutedEventHandlersignature in the UserControl's code-behind.

并在 UserControl 的代码隐藏中定义Copy_Executed具有ExecutedRoutedEventHandler签名的方法。

Then of course do the same thing for ApplicationCommands.Pastewithin the canvas.

然后当然ApplicationCommands.Paste在画布内做同样的事情。

It's up to you whether you want to handle the data within your own application, or use the clipboard. If you're working with images, WPF has a Clipboardclass which can work with BitmapSourceobjects (if you have an Imageelement, chances are its Sourceis already a BitmapSource).

是要在自己的应用程序中处理数据还是使用剪贴板取决于您。如果您正在处理图像,WPF 有一个Clipboard类,它可以与BitmapSource对象一起使用(如果您有一个Image元素,很可能它Source已经是 a BitmapSource)。

回答by Bill Zhang

Firstly, a well designed MVVM application can make copy/paste of user controls much simpler since it will turn to serialize/deserialize CLR objects to Clipboard. WPF will handle user control creation by itself after deserialization.

首先,设计良好的 MVVM 应用程序可以使用户控件的复制/粘贴更加简单,因为它将转向将 CLR 对象序列化/反序列化到剪贴板。WPF 将在反序列化后自行处理用户控件的创建。

If your application does not implement MVVM. You can use XamlWriter/XamlReader to save user controls to XAML and recreate them by yourself. An example:

如果您的应用程序没有实现 MVVM。您可以使用 XamlWriter/XamlReader 将用户控件保存到 XAML 并自行重新创建它们。一个例子:

        StringBuilder outstr = new StringBuilder();

        //this code need for right XML fomating 
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;
        settings.OmitXmlDeclaration = true;
        XamlDesignerSerializationManager dsm =
          new XamlDesignerSerializationManager(XmlWriter.Create(outstr, settings));
        //this string need for turning on expression saving mode 
        dsm.XamlWriterMode = XamlWriterMode.Expression;
        XamlWriter.Save(control, dsm);

        //Read control from XAML
        var frameObject = XamlReader.Parse(outstr.ToString()) as UserControl;
        if (frameObject != null)
            stackPanel.Children.Add(frameObject);

For the part of how to put the XAML string or serialized stream into Clipboard, you can refer to MSDN.

关于如何将XAML字符串或序列化流放入剪贴板的部分,可以参考MSDN。

Hope it can help.

希望它能有所帮助。

回答by Drew Noakes

If you want to bind the command (as @nmclean explains) from code, you can use:

如果要从代码绑定命令(如@nmclean 解释的那样),可以使用:

CommandBindings.Add(new CommandBinding(
    ApplicationCommands.Copy,
    (sender, args) => { /* logic here */ }));