更改“文本框”中的粘贴内容

本文关键字:文本 文本框 更改 | 更新日期: 2023-09-27 18:10:22

如何动态更改文本框中粘贴的内容?

订阅事件:

DataObject.AddPastingHandler (uiTextBox, TextBoxPaste);
下面是我如何定义事件处理程序:
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);
    // I can't just do "args.DataObject.SetData (result)" here.
}

更改“文本框”中的粘贴内容

不能调用args.DataObject。SetData("一些数据"),因为DataObject被冻结了。您可以做的是完全替换DataObject:

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;
 }

我能想到两种方法,没有一种很吸引人:)而且这两种方法都包括取消粘贴命令。

第一种方法是取消粘贴命令,然后计算如果粘贴result,粘贴后文本看起来会是什么样子。

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();
}

另一种方法是取消粘贴命令,更改剪贴板中的文本,然后重新执行粘贴。这还要求您区分实际的粘贴命令和手动调用的粘贴命令。像这样

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;
    }
}

我使用VB.net相当多,我已经测试了这个c#位,我使用了一个转换器,因为我很蹩脚:)

    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);
    }

当控件获得焦点时,我将剪贴板设置为新文本。它存储旧的值。稍后,当控件失去焦点时,剪贴板将被设置回旧值。

只是对@Fredrik的代码做了一些修改,因为我一直在尝试他的两个方法。

第一个是缩短版

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();
}

,另一个更新为保持剪贴板内容

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 = "";
    }
}

我使用的是那些在我的自定义TextBox控制,这就是为什么我可以访问TextBox属性,而不需要先写名字。