由于SilverRore的C1RichTextBox(5.0.20132.340)中的大图像存在问题,我想在自定义控件中实现复制/剪切/粘贴操作。
我正在使用事件C1RichTextBox.ClipboardCopying
和C1RichTextBox.ClipboardPasting
来执行此操作。这些是唯一的事件(没有ClipboardCutting事件),我没有看到任何可重写的方法来解决这个问题。
现在,当我在富文本框中执行CUT操作时,事件C1RichTextBox.ClipboardCopying
也被触发,但我无法确定它是复制还是剪切。内部使用私人成员C1RichTextBox._isCutOperation
。
如何决定是否正在复制或剪切?
答案 0 :(得分:1)
我也在ComponentOne支持论坛中提出了这个问题,这是他们提出的问题:
我建议您更倾听Ctrl + X的KeyDown事件并调用 C1RichTextBox.ClipBoardCut方法。这样你就可以了 处理C1RichTextBox上的cur操作。
这使我得出结论,您无法使用事件ClipboardCopying
来实现自定义复制/剪切操作。
(修改:请参阅this question如何实施自定义复制/剪切/粘贴)
经过几个小时的修补后,我找到了以下解决方案(以防万一其他人为此疯狂):
public class C1RichTextBoxExt : C1RichTextBox
{
public C1RichTextBoxExt( )
{
ClipboardMode = ClipboardMode.RichText;
// Workaround for Copy/Paste issue in C1RichTextBox (5.0.20132.340) -> large images are not copied.
ClipboardCopying += new EventHandler<ClipboardEventArgs>(RichTextBox_ClipboardCopying);
ClipboardPasting += new EventHandler<ClipboardEventArgs>(RichTextBox_ClipboardPasting);
}
void RichTextBox_ClipboardCopying(object sender, ClipboardEventArgs e)
{
// store info in static fields since Silverlight clipboard cannot store html and text at the same time.
_clipboardHtml = Selection.Html;
_clipboardText = Selection.Text;
// Another Workaround: cannot determine if Copy or Cut is going on ...
// -> call the ClipboardCopy() method and let the C1RichTextBox do the cut/copy. Calling this method will
// however trigger the ClipboardCopying event again, so we most remove this method as event handler
// temporarily.
ClipboardCopying -= RichTextBox_ClipboardCopying;
ClipboardCopy();
ClipboardCopying += RichTextBox_ClipboardCopying;
e.Handled = true; // operation is done, nothing more to do.
}
void RichTextBox_ClipboardPasting(object sender, ClipboardEventArgs e)
{
string current = Clipboard.GetText();
// texts will not match exactly since C1 uses a different approach to copy text to the clipboard than
// just using Selection.Text...
if (TextsEqual(current, _clipboardText))
{
// text is the same -> assumption that html is still valid. Paste _clipboardHtml
using (new DocumentHistoryGroup(DocumentHistory)) // enables undo/redo
{
// code from C1 library to paste html correctly ///////////////////
C1Document c1Document = HtmlFilter.ConvertToDocument(_clipboardHtml);
C1TextPointer c1TextPointer = c1Document.ContentStart;
C1TextRange selection = Selection;
C1TextPointer c1TextPointer2 = selection.Delete(!Selection.IsEmpty, false);
List<Type> list = Enumerable.ToList<Type>(Enumerable.Select<C1TextElement, Type>(c1TextPointer2.Element.GetParents(), (C1TextElement elem) => elem.GetType()));
list.Add(c1TextPointer2.Element.GetType());
while (c1TextPointer.Symbol is StartTag && (c1TextPointer.Symbol as Tag).Element is C1Block && !((c1TextPointer.Symbol as Tag).Element is C1TableRowGroup) && list.Contains((c1TextPointer.Symbol as Tag).Element.GetType()))
{
c1TextPointer = c1TextPointer.GetPositionAtOffset(1);
}
C1TextPointer c1TextPointer3 = c1Document.ContentEnd;
while (c1TextPointer3.PreviousSymbol is EndTag)
{
c1TextPointer3 = c1TextPointer3.GetPositionAtOffset(-1);
}
c1Document.FragmentRange = new C1TextRange(c1TextPointer, c1TextPointer3);
selection.Fragment = c1Document;
Selection = new C1TextRange(selection.End);
Focus();
// end of C1 library code ////////////////////////
}
e.Handled = true; // paste is done
}
else
{
// text is different -> something newer got copied from another control or application
// -> let C1RichTextBox paste
}
}
private bool TextsEqual(string t1, string t2)
{
if (string.IsNullOrEmpty(t1) || string.IsNullOrEmpty(t2))
{
return false;
}
IEnumerable<char> chars1 = t1.Where(c => Char.IsLetterOrDigit(c));
t1 = new string(chars1.ToArray());
IEnumerable<char> chars2 = t2.Where(c => Char.IsLetterOrDigit(c));
t2 = new string(chars2.ToArray());
return t1 == t2;
}
private static string _clipboardText;
private static string _clipboardHtml;
}