Change paste contents in Textbox

后端 未结 4 1634
逝去的感伤
逝去的感伤 2020-12-05 14:44

How can I dynamically change the contents of what will be pasted in the TextBox.

Here is how I subscribe to the event:

DataObject.AddPastingHandler (         


        
相关标签:
4条回答
  • 2020-12-05 15:15

    Just some modifications of @Fredrik's code, since I've been trying out both of his methods.

    First one is just a shortened version

    private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e)
    {
        string clipboard = e.DataObject.GetData(typeof(string)) as string;
        Regex nonNumeric = new System.Text.RegularExpressions.Regex (@"\D");
        string result = nonNumeric.Replace(clipboard, string.Empty);
    
        int caret = CaretIndex;
        Text = Text.Substring(0, SelectionStart) + result +
            Text.Substring(SelectionStart + SelectionLength);
        CaretIndex = caret + result.Length;
    
        e.CancelCommand();
    }
    

    and the other one is updated with keeping the clipboard content

    private string oldClipboardContent { get; set; } = "";
    private bool pasteModified { get; set; } = false;
    
    private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e)
    {
        if (pasteModified)
        {
            pasteModified = false;
        }
        else
        {
            pasteModified = true;
    
            string text = (string)e.DataObject.GetData(typeof(string));
            oldClipboardContent = text;
    
            Regex nonNumeric = new System.Text.RegularExpressions.Regex (@"\D");
            text = nonNumeric.Replace(text, string.Empty);
            e.CancelCommand();
    
            Clipboard.SetData(DataFormats.Text, text);
            ApplicationCommands.Paste.Execute(text, this);
    
            Clipboard.SetData(DataFormats.Text, OldClipboardContent);
            oldClipboardContent = "";
        }
    }
    

    I was using those inside my custom TextBox control, that is why I could access TextBox properties without writing the name first.

    0 讨论(0)
  • 2020-12-05 15:24

    I use VB.net quite a bit, I've tested this C# bit, I used a converter because I'm lame :)

        string oClipboard;
    
        private void TextBox1_GotFocus(object sender, System.EventArgs e)
        {
            oClipboard = Clipboard.GetText();
            Clipboard.SetText("foo");
        }
    
        private void TextBox1_LostFocus(object sender, System.EventArgs e)
        {
            Clipboard.SetText(oClipboard);
        }
    

    I set the clipboard to the new text when the control gets focus. It stores the old value. Later, when the control loses focus, the clipboard is set back to the old value.

    0 讨论(0)
  • 2020-12-05 15:33

    I can think of two ways, none of which are very attractive :) And both ways include canceling the paste command.

    The first way would be to cancel the paste command and then calculate what the text would look like after the paste if result was pasted instead.

    private void TextBoxPaste(object sender, DataObjectPastingEventArgs args)
    {
        string clipboard = args.DataObject.GetData(typeof(string)) as string;
    
        Regex nonNumeric = new System.Text.RegularExpressions.Regex(@"\D");
        string result = nonNumeric.Replace(clipboard, String.Empty);
    
        int start = uiTextBox.SelectionStart;
        int length = uiTextBox.SelectionLength;
        int caret = uiTextBox.CaretIndex;
    
        string text = uiTextBox.Text.Substring(0, start);
        text += uiTextBox.Text.Substring(start + length);
    
        string newText = text.Substring(0, uiTextBox.CaretIndex) + result;
        newText += text.Substring(caret);
        uiTextBox.Text = newText;
        uiTextBox.CaretIndex = caret + result.Length;
    
        args.CancelCommand();
    }
    

    The other way would be to cancel the paste command, change the text in the Clipboard and then re-execute paste. This would also require you to differ between the real paste command and the manually invoked paste command. Something like this

    bool m_modifiedPaste = false;
    private void TextBoxPaste(object sender, DataObjectPastingEventArgs args)
    {
        if (m_modifiedPaste == false)
        {
            m_modifiedPaste = true;
            string clipboard = args.DataObject.GetData(typeof(string)) as string;
    
            Regex nonNumeric = new System.Text.RegularExpressions.Regex(@"\D");
            string result = nonNumeric.Replace(clipboard, String.Empty);
    
            args.CancelCommand();
    
            Clipboard.SetData(DataFormats.Text, result);
            ApplicationCommands.Paste.Execute(result, uiTextBox);
        }
        else
        {
            m_modifiedPaste = false;
        }
    }
    
    0 讨论(0)
  • 2020-12-05 15:34

    You cannot call args.DataObject.SetData("some data") since the DataObject is frozen. What you can do is replace the DataObject altogether:

    private void TextBoxPaste(object sender, DataObjectPastingEventArgs e) {
            string text = (String)e.DataObject.GetData(typeof(String));
            DataObject d = new DataObject();
            d.SetData(DataFormats.Text, text.Replace(Environment.NewLine, " "));
            e.DataObject = d;
     }
    
    0 讨论(0)
提交回复
热议问题