Paste Event in a Wpf Textbox

Paste Event in a WPF TextBox

Here's some code I had lying around in case I ever needed it. Might help you.

public Window1()
{
InitializeComponent();

// "tb" is a TextBox
DataObject.AddPastingHandler(tb, OnPaste);
}

private void OnPaste(object sender, DataObjectPastingEventArgs e)
{
var isText = e.SourceDataObject.GetDataPresent(DataFormats.UnicodeText, true);
if (!isText) return;

var text = e.SourceDataObject.GetData(DataFormats.UnicodeText) as string;
...
}

MVVM catch textbox paste event

In view :

<TextBox Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="120" Height="200"/>

In view model :

class MainWindowViewModel : BindableBase
{
private string text;

public string Text
{
get { return text; }
set { SetProperty(ref text, value); }
}
}

In this way, when you paste the text or press Ctrl+V the Text value is updated and PropertyChanged event is raised. Thus you can identify the pasted text into textbox.

If you want to identify Ctrl+V for some special reason, try this :

void AssociatedObject_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.V)
{
// Your action
}
}

WPF handling text, image and file pasting event

You could handle the ApplicationCommands.Paste command something like this to get the pasted in text, file(s) or image:

private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
if (e.Command == ApplicationCommands.Paste)
{
var files = Clipboard.GetFileDropList();
var text = Clipboard.GetData(DataFormats.Text);
var image = Clipboard.GetImage();
e.Handled = true;
}
}

How to simulate Paste in a WPF TextBox?

Invoke the ApplicationCommand Paste:

ApplicationCommands.Paste.Execute(this, pastedText)

Please note that this will not work in partial trust!

Allowing 'pasting data' into a WPF textbox

You can use CommandManager.PreviewExecuted and CommandManager.PreviewCanExecute routed events to handle your pasting logic.

For example, let's suppose you want to accept an image from the clipboard when a user tries to paste it into your TextBox. So first, define the methods that will handle both events:

    private void onPreviewCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
// In this case, we just say it always can be executed (only for a Paste command), but you can
// write some checks here
if (e.Command == ApplicationCommands.Paste)
{
e.CanExecute = true;
e.Handled = true;
}
}

private void onPreviewExecuted(object sender, ExecutedRoutedEventArgs e)
{
// If it is a paste command..
if (e.Command == ApplicationCommands.Paste)
{
// .. and the clipboard contains an image
if (Clipboard.ContainsImage())
{
// proccess it somehow
e.Handled = true;
}

}
}

Then, you have to associate those methods with the routed events (this could go in the constructor, for example):

CommandManager.AddPreviewExecutedHandler(myTextBox, onPreviewExecuted);
CommandManager.AddPreviewCanExecuteHandler(myTextBox, onPreviewCanExecute);

And it should work with both the keyboard shortcut and the menu 'button'.

It is important to handle the PreviewCanExecute event. By default, the TextBox will only accept text as a 'pasteable' content, so you need to mark that content somehow in order to paste it.

EDIT:
Also, it is a good practice to remove the 'listeners' from the event if you can. As you're using behaviors, you can do this by overriding the 'OnDetaching' method in your behavior. This could prevent memory leaks if the events are not Weak Events:

    protected override void OnDetaching()
{
base.OnDetaching();
CommandManager.RemovePreviewExecutedHandler(myTextBox, onPreviewExecuted);
CommandManager.RemovePreviewCanExecuteHandler(myTextBox, onPreviewCanExecute);
}

Using Textbox pasting event in Code Behind with MVVM Design Pattern?

A cleaner approach, IMHO, is to either use INotifyDataErrorInfo or ValidationRule

They both have their place in validation scheme. INotifyDataErrorInfo is more closely bound to the type, and ValidationRule is loosely coupled to validate an instance.

Here is some information on how to use Validation Rules and INotifyDataErrorInfo

Change paste contents in Textbox

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


Related Topics



Leave a reply



Submit