在文本框中更改粘贴内容

如何动态更改将在TextBox中粘贴的内容。

以下是我订阅活动的方式:

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

我可以想到两种方式,其中没有一种非常有吸引力:)两种方式都包括取消粘贴命令。

第一种方法是取消粘贴命令,然后计算粘贴后文本的内容,如果粘贴了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; } } 

因为DataObject被冻结,所以不能调用args.DataObject.SetData(“some data”)。 你可以做的是完全替换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; } 

我使用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属性而不首先编写名称。