【问题标题】:How to copy IDataObject value to another IDataObject?如何将 IDataObject 值复制到另一个 IDataObject?
【发布时间】:2020-09-09 20:37:38
【问题描述】:

我想在 C# 中从“d”IDataObject 到“c”IDataObject 获取值,但即使我不单击 D 键,我的“c”也拥有剪贴板中的值。如何将一个 IDataObject 的独立值赋予第二个?

第一个函数:

if (Keyboard.IsKeyDown(Key.D))
{
    d = Clipboard.GetDataObject();
    c = d;      // <-- doesn't work
    string dd = d.GetData(DataFormats.Text).ToString();      //content
    MessageBox.Show(dd);
}

第二个功能

if (Keyboard.IsKeyDown(Key.S))
{
    string dd = c.GetData(DataFormats.Text).ToString();      //content
    MessageBox.Show(dd);
}

【问题讨论】:

  • 剪贴板可能包含您无法按原样复制到对象的元数据。顺便说一句,问题不清楚。你想达到什么目标?从哪里复制数据以及复制到哪里?为什么Clipboard?什么条件?在一个应用程序或不同的应用程序内?您是否需要剪贴板监听,例如当其他一些应用程序修改它并且您想读取更改时,例如虚拟按下Ctrl+C后? IDataObject 是对数据的引用,而不是数据本身。
  • 我要单击 CTRL + C。我的 d 中有值。当我单击 D 键时,这会显示它使用消息框并复制到 c。现在我再次单击 ctrl + c 标记另一个文本。之后,当我单击 S 键时,它应该从第一个 ctrl + c 显示我的旧值,但我有来自实际剪贴板的内容。
  • 我希望你知道我在说什么兄弟。
  • 我想从一个变量获取内容(文本或图像)到不同的变量,但即使是文本或图像也应该接受它。

标签: c# wpf copy clipboard idataobject


【解决方案1】:

为什么需要IDataObject 的备份?

如果在所有情况下都有可能,它会是这样的

备份

// expiremental list of formats to exclude. Doesn't cover all possible cases but most of it.
private static readonly string[] clipboardMetaFormats = { "application/x-moz-nativeimage", "FileContents", "EnhancedMetafile", "System.Drawing.Imaging.Metafile", "MetaFilePict", "Object Descriptor", "ObjectLink", "Link Source Descriptor", "Link Source", "Embed Source", "Hyperlink" };

private DataObject ReadClipboard()
{
    DataObject result = new DataObject();
    IDataObject dataObject = Clipboard.GetDataObject();
    string[] formats = dataObject.GetFormats()?.Except(clipboardMetaFormats).ToArray() ?? Array.Empty<string>();
    foreach (string format in formats)
    {
        try
        {
            object data = dataObject.GetData(format);
            if (data != null) result.SetData(format, data);
        }
        catch (ExternalException ex)
        { 
            Debug.WriteLine($"Error {ex.ErrorCode}: {ex.Message}");
        }
    }
    return result;
}
DataObject backup = ReadClipboard();

然后您可以将其用作本地数据存储。例如,如果您想更改 Clipboard,请使用更改后的值,例如将其粘贴到某个应用程序中并将以前的数据恢复到Clipboard

恢复

private void UpdateClipboard(DataObject data)
{
    if (data == null) return;
    try
    {
        Clipboard.SetDataObject(data);
    }
    catch (ExternalException ex)
    {
        Debug.WriteLine($"Error {ex.ErrorCode}: {ex.Message}");
    }
}
UpdateClipboard(backup);

但在您的情况下,这是一个简单的string。你可以这样做:

string text = Clipboard.GetText(TextDataFormat.UnicodeText);
Clipboard.SetText(text, TextDataFormat.UnicodeText);

【讨论】:

  • 我需要备份因为我想创建多剪贴板功能,当用户单击 ctrl+c 程序时应将其保存到变量中。当用户再次单击 ctrl+c 时,旧的剪贴板内容应该转到不同的变量,当我单击一个键时,我的实际剪贴板值应该被旧的替换。我有这个功能,但只有文本。我需要为文本和图像调整它(我们可以使用 printscreen 按钮,它的工作方式类似于 ctrl + c 对)
  • @DawidSochiiSokół 试试这个解决方案。
  • 我会尝试但明天给你反馈。提前致谢。
  • 您的代码有效!非常感谢!我只有一个问题要问你。你从哪里得到这方面的信息?我想了解有关您的代码的更多信息。你有任何有用的链接来阅读它吗?
  • @DawidSoChiiSokół IDataObjectClipboard 创建的对象的接口,并且每次剪贴板更改时都会销毁该对象。此外Clipboard 可能包含无法备份到object 实例的元数据,应该有更复杂的解决方案来备份它。因此,当您尝试复制整个 DataObject 时,我会忽略这些事情并导致 Exception。因此,我按格式复制格式,忽略了我发现无法复制的所有内容。反过来,它只需将整个DataObject 设置为Clipboard。我不知道在哪里阅读。
猜你喜欢
  • 2011-02-11
  • 1970-01-01
  • 2012-10-22
  • 1970-01-01
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-23
相关资源
最近更新 更多