1

C1RichTextBox for Silverlight (5.0.20132.340) の大きな画像に関する問題のため、カスタム コントロールにコピー/切り取り/貼り付け操作を実装したいと考えています。私はこれを行うためにイベントC1RichTextBox.ClipboardCopyingを使用C1RichTextBox.ClipboardPastingしています。これらは唯一のイベント (ClipboardCutting イベントではありません) であり、これを別の方法で解決するためのオーバーライド可能なメソッドはありません。

リッチ テキスト ボックスで CUT 操作を実行すると、イベントC1RichTextBox.ClipboardCopyingも発生しますが、コピーかカットかを判断できません。C1RichTextBox._isCutOperation内部で使用されるプライベートメンバーがあります。

コピーまたはカットが実行されているかどうかを判断する方法はありますか?

4

1 に答える 1

1

また、ComponentOne サポート フォーラムでこの質問をしたところ、次のような回答がありました。

Ctrl+X の KeyDown イベントをリッスンし、C1RichTextBox.ClipBoardCut メソッドを呼び出すことをお勧めします。このようにして、C1RichTextBox で cur 操作を処理できます。

ClipboardCopyingこれにより、イベントを使用してカスタムのコピー/カット操作を実装できないという結論に達しました。

編集:カスタムコピー/カット/ペーストを実装する方法については、この質問を参照してください)

数時間いじくり回した後、次の解決策を見つけました(他の誰かがこれに夢中になっている場合に備えて):

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;
}
于 2013-11-15T10:21:38.127 に答える