Как установить HTML в буфер обмена на С#?

Я хочу поместить богатый текст в HTML в буфер обмена, поэтому, когда пользователи вставляют в Word, он будет содержать исходное HTML-форматирование.

Использование метода Clipboard.SetText не работает.

Кроме того, я хотел бы, чтобы, если пользователи вставляются в богатый редактор, например Word, он вставляет форматированный текст, и если они вставляются в обычный редактор, например "Блокнот", он вставляет простой текст.

Ответ 1

При настройке HTML-текста вам необходимо предоставить заголовок с дополнительной информацией о том, какой фрагмент html, который вы на самом деле хотите вставить, будучи в состоянии обеспечить дополнительный стиль вокруг него:

Version:0.9
StartHTML:000125
EndHTML:000260
StartFragment:000209
EndFragment:000222
<HTML>
<head>
<title>HTML clipboard</title>
</head>
<body>
<!–StartFragment–><b>Hello!</b><!–EndFragment–>
</body>
</html>

С заголовком (и правильными индексами) вызов Clipboard.SetText с помощью TextDataFormat.Html сделает трюк.

Чтобы обрабатывать HTML и текстовые пасты, вы не можете использовать метод Clipboard.SetText, так как он очищает буфер обмена каждый раз при его вызове; вам нужно создать экземпляр DataObject, вызвать его метод SetData один раз с HTML и один раз с открытым текстом, а затем установить объект в буфер обмена с помощью Clipboard.SetDataObject.

Обновление

См. "Настройка HTML/Text в Clipboard revisited" для более подробной информации и реализации ClipboardHelper.

Ответ 2

Я нашел код: https://www.experts-exchange.com/questions/21966855/Create-a-hyperlink-in-VB-net-copy-to-clipboard-Should-be-able-to-paste-hyperlink-in-Microsoft-Word-Excel.html

Этот код обрабатывает проблемы обновления начальных и конечных индексов.

Преобразован в С#:

public void AddHyperlinkToClipboard(string link, string description)
{
    const string sContextStart = "<HTML><BODY><!--StartFragment -->";
    const string sContextEnd = "<!--EndFragment --></BODY></HTML>";
    const string m_sDescription = "Version:1.0" + Constants.vbCrLf + "StartHTML:aaaaaaaaaa" + Constants.vbCrLf + "EndHTML:bbbbbbbbbb" + Constants.vbCrLf + "StartFragment:cccccccccc" + Constants.vbCrLf + "EndFragment:dddddddddd" + Constants.vbCrLf;

    string sHtmlFragment = "<A HREF=" + Strings.Chr(34) + link + Strings.Chr(34) + ">" + description + "</A>";

    string sData = m_sDescription + sContextStart + sHtmlFragment + sContextEnd;
    sData = sData.Replace("aaaaaaaaaa", m_sDescription.Length.ToString().PadLeft(10, '0'));
    sData = sData.Replace("bbbbbbbbbb", sData.Length.ToString().PadLeft(10, '0'));
    sData = sData.Replace("cccccccccc", (m_sDescription + sContextStart).Length.ToString().PadLeft(10, '0'));
    sData = sData.Replace("dddddddddd", (m_sDescription + sContextStart + sHtmlFragment).Length.ToString().PadLeft(10, '0'));
    sData.Dump();
    Clipboard.SetDataObject(new DataObject(DataFormats.Html, sData), true );
}

Ответ 3

Артур прав о заголовке, но важно отметить, что данные не будут в буфере обмена в виде обычного текста. Вы должны использовать CF_HTML. Вы можете прочитать об этом в MSDN: http://msdn.microsoft.com/en-us/library/aa767917(v=vs.85).aspx Чтобы быть правильным, у вас будет CF_TEXT, показывающий просто: "Hello!", А затем CF_HTML с заголовком и данными HTML, как в примере Артура.