Próbuję przechwycić dane wklejone w polu tekstowym WPF.Umożliwianie "wklejania danych" do pola tekstowego WPF
Na przykład użytkownik tworzy zrzut ekranu za pomocą narzędzia wycinania systemu Windows, , które automatycznie umieszcza dane obrazu w schowku. Pomysł polega na tym, aby użytkownik mógł po prostu CTRL + V na TextBox, aby móc go przechwycić, sprawdzić, czy jest to dane , a następnie zrobić, co chcę z nim.
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);
}
}
Korzystanie z zachowaniem wyżej kod nie uzyskać wyzwolone, gdy tekst jest wklejany do pola tekstowego ale wydaje TextBox nie pozwala na nic innego do wklejenia więc nawet nie osiągnie tego kodu, jeśli to nie jest tekst .
Zastanawiam się, czy istnieje właściwość, która musi być ustawiony na TextBox, lub coś innego które pozwoliłyby dane do wklejenia (chociaż nigdy TextBox może wyświetlać te dane)
Jeśli nie , jakie elementy interfejsu użytkownika pozwalają na wklejenie danych, ponieważ mogę je wykorzystać na swoją korzyść.
Aktualizacja Ktoś pisał do mnie, że będę musiał użyć RichTextBox aby umożliwić wklejenie
takiego, który nie jest coś, co mogę używać, więc postanowiłem wziąć inne podejście (nieco 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();
}
}
}
To pozwala mi przenieść zdjęcia i pliki do TextBox, ale tylko używając klawiszy Ctrl + V, a nie za pomocą menu kontekstowego domyślne TextBox.
Więc nadal jestem zainteresowany wiedząc, jeśli istnieje lepszy/łatwiejszy sposób
Aktualizacja 2 podstawie roztworu przez Daniela, który działa bardzo dobrze, mam zaktualizowała OnAttached:
protected override void OnAttached()
{
base.OnAttached();
CommandManager.AddPreviewCanExecuteHandler(AssociatedObject, onPreviewCanExecute);
CommandManager.AddPreviewExecutedHandler(AssociatedObject, onPreviewExecuted);
}
I usunięto obiekt PreviewKeyDownHandler.
W jednym ze swoich fragmentów kodu, obsługujesz CTRL + V jawnie - nigdy tego nie rób! - użytkownik może na przykład wkleić skonfigurowaną inną kombinację klawiszy. Musi być szerszy komunikat "Wklej" z systemu operacyjnego, z którym możesz sobie poradzić. – BrainSlugs83