WPF テキスト ボックスに貼り付けられたデータを傍受しようとしています。
たとえば、ユーザーが Windows のスニッピング ツールを使用して画面キャプチャを作成すると、画像データがクリップボードに自動的に配置されます。ここでのアイデアは、ユーザーが TextBox で単に CTRL+V を実行できるようにして、それをインターセプトし、それがデータであるかどうかを確認してから、必要なことを何でもできるようにすることです。
public class PasteBehavior : Behavior<UIElement>
{
protected override void OnAttached()
{
base.OnAttached();
DataObject.AddPastingHandler(AssociatedObject, new DataObjectPastingEventHandler(OnPaste));
}
protected override void OnDetaching()
{
base.OnDetaching();
}
private void OnPaste(object sender, DataObjectPastingEventArgs e)
{
if (e.SourceDataObject.GetDataPresent(DataFormats.Text))
return;
var formats = e.SourceDataObject.GetFormats();
foreach (var format in formats)
Console.WriteLine(format);
}
}
上記の動作を使用すると、テキストが TextBox に貼り付けられたときにコードがトリガーされますが、TextBox は他のものを貼り付けることを許可していないように見えるため、テキストでない場合はこのコードに到達することさえありません。
TextBoxに設定する必要があるプロパティ、またはデータを貼り付けることができる何かがありますか(TextBoxはそのデータを表示できませんが)
そうでない場合、どの UI 要素がデータの貼り付けを許可しているか、それを自分の利点としても利用できる可能性があります。
更新
誰かが私に、このような貼り付けを許可するには RichTextBox を使用する必要があると投稿しましたが
、これは私が使用できるものではないため、別の (ややハッキーな) アプローチを取ることにしました。
public class PasteBehavior : Behavior<UIElement>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.PreviewKeyDown += AssociatedObject_PreviewKeyDown;
}
void AssociatedObject_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.V)
{
if (Clipboard.ContainsData(DataFormats.Dib))
{
using (var stream = new MemoryStream())
{
var image = Clipboard.GetImage();
var message = new ImagePastedMessage()
{
ImageData = GetImagePngData(image)
};
Messenger.Default.Send(message);
}
e.Handled = true;
}
else if (Clipboard.ContainsFileDropList())
{
var results = Clipboard.GetFileDropList();
var filenames = new string[results.Count];
results.CopyTo(filenames, 0);
var message = new FilesDroppedMessage()
{
Filenames = filenames
};
Messenger.Default.Send(message);
e.Handled = true;
}
}
}
protected override void OnDetaching()
{
base.OnDetaching();
}
private byte[] GetImagePngData(BitmapSource source)
{
using (var stream = new MemoryStream())
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(source));
encoder.Save(stream);
return stream.ToArray();
}
}
}
これにより、画像とファイルを TextBox に貼り付けることができますが、TextBox のデフォルトのコンテキスト メニューを使用せずに CTRL+V キーのみを使用できます。
だから私はまだより良い/より簡単な方法があるかどうかを知りたいと思っています
更新 2 非常にうまく機能する Daniel のソリューションに基づいて、OnAttached を更新しました。
protected override void OnAttached()
{
base.OnAttached();
CommandManager.AddPreviewCanExecuteHandler(AssociatedObject, onPreviewCanExecute);
CommandManager.AddPreviewExecutedHandler(AssociatedObject, onPreviewExecuted);
}
また、PreviewKeyDownHandler を削除しました。