Работа с классом «Буфер обмена» через .NET (Windows Forms) в Visual Studio / TFS 2010. Элементы управления WorkItem работают на некоторых компьютерах, а на некоторых - нет? - PullRequest
0 голосов
/ 15 августа 2011

Я помещаю экземпляр сериализуемого класса в буфер обмена Windows с помощью:

Clipboard.Clear();
Clipboard.SetData("MyCustomDataFormatName", serializableInstance);

И звонит

dataObject.GetDataPresent("MyCustomDataFormatName")

возвращает true на всех машинах. Тем не менее, пытаясь извлечь данные из буфера обмена, как это

var dataObject = Clipboard.GetDataObject();
object clipboardData = dataObject.GetData("MyCustomDataFormatName");

отлично работает на некоторых машинах, на некоторых - нет, в частности, вызов GetData (..) всегда возвращает false на них (опять же, GetDataPresent () возвращает true на любой машине).

Этот код работает в Visual Studio 2010 и представляет собой пользовательский элемент управления TFS / Team Systems 2010. Копирование и вставка выполняются на одном и том же компьютере (x86) во всех случаях, и классы не изменяются. Это только потому работает или не работает. Перезагрузка и закрытие всех других приложений, которые могут потреблять / блокировать буфер обмена («может»), не помогает.

Класс, который используется для вызовов SetData () / GetData (), является универсальным контейнером:

[Serializable]
public class ClipboardContainer<T> where T : class
{
    private readonly string _data;

    /// <summary>
    /// Gets the data.
    /// </summary>
    /// <value>The data.</value>
    public T Data
    {
        get
        {
            return DeserializeDataObject(_data);
        }
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="ClipboardContainer&lt;T&gt;"/> class.
    /// </summary>
    /// <param name="dataObject">The data object.</param>
    internal ClipboardContainer(T dataObject)
    {
        _data = SerializeDataObject(dataObject);
    }

    /// <summary>
    /// Serializes the data object.
    /// </summary>
    /// <param name="dataObject">The data object.</param>
    /// <returns></returns>
    private static string SerializeDataObject(T dataObject)
    {
        if (!typeof(T).IsSerializable) throw new SerializationException("dataObject cannot be serialized.");

        var dataContractSerializer = new DataContractSerializer(typeof(T));

        using (var stringWriter = new StringWriter())
        {
            using (var xmlTextWriter = new XmlTextWriter(stringWriter))
            {
                dataContractSerializer.WriteObject(xmlTextWriter, dataObject);
            }

            return stringWriter.ToString();
        }
    }

    /// <summary>
    /// Deserializes the data object.
    /// </summary>
    /// <param name="objectData">The object data.</param>
    /// <returns></returns>
    private static T DeserializeDataObject(string objectData)
    {
        if (!typeof(T).IsSerializable) throw new SerializationException("Object cannot be deserialized.");

        var dataContractSerializer = new DataContractSerializer(typeof(T));

        T result;
        using (var xr = XmlReader.Create(new StringReader(objectData)))
        {
            result = ((T)dataContractSerializer.ReadObject(xr));
        }

        return result;
    }
}

Но в основном единственным постоянным типом данных является строка внутри экземпляров этих контейнеров, поэтому ничего особенного не происходит.

Что-то я делаю не так или есть решение / обходной путь?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...