web-dev-qa-db-ja.com

クリップボードオブジェクトのコピーとの間でオブジェクトをコピーする

オブジェクトをWindowsクリップボードにコピーして、もう一度オフにしようとしています。私のコードは次のようなものです:

クリップボードにコピーします。

_Clipboard.Clear();
DataObject newObject = new DataObject(prompts);
newObject.SetData(myString);
Clipboard.SetDataObject(newObject);
_

ここで、promptsは_List<Data.Sources.PromptResult>_コレクションです。

クリップボードからコピー:

_IDataObject dataObject = System.Windows.Forms.Clipboard.GetDataObject();
if (dataObject.GetDataPresent(typeof(List<Data.Sources.PromptResult>)))
{
  Type type = typeof(List<Data.Sources.PromptResult>);
  Object obj = dataObject.GetData(type);
  return (List<Data.Sources.PromptResult>)dataObject.GetData(type);
}
_

GetFormats()は形式をリストにあるものとして示し、GetDataPresent(List<Data.Sources.PromptResult>)はtrueを返しますが、オブジェクトをClipboardクラスからGetData(List<Data.Sources.PromptResult>)nullが返されます。

誰かが何が間違っているのか考えていますか?

12
James

OKユーザータイプのリストをクリップボードに追加して元に戻そうとしました...これが私が試したことです:

私のユーザークラス:

public class User
{
   public int Age { get; set; }
   public string Name { get; set; }
}

残りのコード:

// Create User list and add some users
List<User> users = new List<User>();
users.Add(new User { age = 15, name = "Peter" });
users.Add(new User { age = 14, name = "John" });

// Lets say its my data format
string format = "MyUserList";
Clipboard.Clear();

// Set data to clipboard
Clipboard.SetData(format, users);

// Get data from clipboard
List<User> result = null;
if (Clipboard.ContainsData(format))
    result = (List<User>)Clipboard.GetData(format);

...そして結果はnull :) ... UserクラスをSerializableとしてマークするまで

[Serializable]
public class User
{ 
    //...   
}

その後、私のコードは機能しました。 Ok答えではありませんが、何らかの形で役立つかもしれません。

15
Reniuz

@Reniuzあなたの助けに感謝しますそれは私が答えを見つけるのを助けました。

複数の形式でクリップボードからテキストとカスタムオブジェクトデータを取得するために、私は自分のクラスにIDataObjectインターフェイスを実装しました。データオブジェクトを設定するコードでは、コピーフラグを次のように設定する必要があります。

Clipboard.Clear();
Clipboard.SetDataObject(myClassThatImplementsIDataObject, true);

データを再度取得するには、次を使用して標準テキストを取得できます。

Clipboard.GetText();

データは、dataメソッドを使用して取得できます。

Clipboard.GetData("name of my class");

もう1つの有用な点は、クリップボードに入れていたオブジェクトがBinaryFormatterクラスを使用してシリアル化できるかどうかをテストすることでした...例外がスローされた場合、クリップボードへのコピーも失敗しますが、サイレントです。

だから私のクラスは:

[Serializable]
public class ClipboardPromptsHolder : IDataObject
{
    ...
}
4
James

同様のシナリオがあり、クラスをシリアル化可能としてマークした後、それを機能させました。

したがって、Serializable属性をクラスData.Sources.PromptResultに配置してみてください。

3
granaker

クラスが別のクラスから派生している場合は、基本クラスも[Serializable]にする必要があることがわかりました。そうしないと、そのレシピが機能しません。私の場合、それは次のようなものでした

public abstract class MyAbstractUser
{
...
}

[Serializable]
public class MyUser : MyAbstractUser
{
...
}

クリップボードを介してMyUserの値を交換しようとすると機能しませんでしたが、MyAbstractUserに[Serializable]を追加すると機能しました。

0
Alex Konnen

アイテムのリストをクリップボードに送信しようとしたときに、これに遭遇しました。私が必要としていたのは、オブジェクト全体ではなく、それらのアイテムの文字列表現でした。私はここでいくつかの提案を試しましたが、役に立ちませんでした。しかし、私は自分の解決策を思いついたので、それを共有したいと思いました。下記参照。

public static void CopyToClipboard<T>(this IEnumerable<T> items)
{
    StringBuilder stringBuilder = new StringBuilder();

    foreach (T item in items)
        stringBuilder.Append(item.ToString()).AppendLine();

    Clipboard.SetText(stringBuilder.ToString());
}

これを拡張メソッドとして追加し、カスタムTypeのToString()メソッドを必ずオーバーライドしてください。

0
JasonG