Tôi đang cố chặn dữ liệu được dán vào hộp văn bản WPF.Cho phép 'dán dữ liệu' vào hộp văn bản WPF
Ví dụ: người dùng tạo ảnh chụp màn hình bằng công cụ bẻ khóa Windows, tự động đặt dữ liệu hình ảnh vào khay nhớ tạm. Ý tưởng ở đây là để cho phép người dùng chỉ đơn giản là CTRL + V trên TextBox để tôi có thể chặn nó, kiểm tra xem đó là dữ liệu và sau đó làm bất cứ điều gì tôi muốn với nó.
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);
}
}
Sử dụng các hành vi trên, các mã này được kích hoạt khi văn bản được dán vào TextBox nhưng nó sẽ có vẻ TextBox không cho phép bất cứ điều gì khác để được dán nên nó không bao giờ thậm chí đạt đến mã này nếu nó không phải là văn bản .
Tôi đang tự hỏi, liệu có một tài sản cần phải được thiết lập trên TextBox, hay cái gì khác mà sẽ cho phép dữ liệu được dán (mặc dù TextBox không bao giờ có thể hiển thị dữ liệu đó)
Nếu không , các yếu tố giao diện người dùng nào cho phép dán dữ liệu, vì tôi cũng có thể sử dụng các yếu tố đó cho lợi thế của mình.
Cập nhật người gửi ra cho tôi rằng tôi sẽ phải sử dụng một RichTextBox để cho phép dán
như thế này, mà không phải là điều mà tôi có thể sử dụng, vì vậy tôi quyết định tham gia một cách tiếp cận khác nhau (hơi hacky) :
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();
}
}
}
này cho phép tôi để dán hình ảnh và các tập tin vào TextBox nhưng chỉ sử dụng + V phím CTRL, không sử dụng menu ngữ cảnh mặc định của TextBox.
Vì vậy, tôi vẫn muốn biết nếu có một/cách tốt hơn dễ dàng hơn
Cập nhật 2 Dựa trên các giải pháp của Daniel, trong đó hoạt động thực sự tốt, tôi đã cập nhật các OnAttached:
protected override void OnAttached()
{
base.OnAttached();
CommandManager.AddPreviewCanExecuteHandler(AssociatedObject, onPreviewCanExecute);
CommandManager.AddPreviewExecutedHandler(AssociatedObject, onPreviewExecuted);
}
Và xóa tệp PreviewKeyDownHandler.
Trong một trong các đoạn mã của bạn, bạn đang xử lý CTRL + V một cách rõ ràng - đừng bao giờ làm điều đó! - ví dụ: người dùng có thể đã dán cấu hình là một tổ hợp phím khác. Phải có thông báo "Dán" rộng hơn từ hệ điều hành mà bạn có thể xử lý. – BrainSlugs83