Sto provando ad intercettare i dati incollati in una casella di testo WPF.Consentire 'incolla dati' in una casella di testo WPF
Ad esempio, l'utente crea un'acquisizione di schermate con lo strumento di snipping di Windows, che colloca automaticamente i dati dell'immagine negli Appunti. L'idea qui è di consentire all'utente di semplicemente CTRL + V sul TextBox in modo che io possa intercettarlo, controllare se si tratta di dati e quindi fare quello che voglio con esso.
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);
}
}
Utilizzando il comportamento precedente, il codice venga attivato quando il testo viene incollato in TextBox ma sembrerebbe TextBox non consente altro per essere incollato in modo che non raggiunge mai, anche questo codice se non è il testo .
mi chiedo, c'è una proprietà che deve essere impostata sul TextBox, o qualcos'altro che permetterebbe ai dati di essere incollati (anche se il TextBox non potrà mai visualizzare i dati)
caso contrario , quali elementi dell'interfaccia utente consentono di incollare i dati, poiché potrei essere in grado di utilizzarli a mio vantaggio.
Aggiornamento qualcuno ha postato a me che avrei dovuto usare un RichTextBox per consentire incollare
come questo, che non è qualcosa che posso usare, così ho deciso di adottare un approccio diverso (un po '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();
}
}
}
Questo mi permette di incollare immagini e file nella casella di testo, ma solo utilizzando i tasti CTRL + V, non utilizzando il menu contestuale di default del controllo TextBox.
Quindi sono ancora interessato a sapere se c'è un modo migliore/più facile
Update 2 Sulla base della soluzione di Daniel, che funziona davvero bene, ho aggiornato il OnAttached:
protected override void OnAttached()
{
base.OnAttached();
CommandManager.AddPreviewCanExecuteHandler(AssociatedObject, onPreviewCanExecute);
CommandManager.AddPreviewExecutedHandler(AssociatedObject, onPreviewExecuted);
}
E rimosso PreviewKeyDownHandler.
In uno dei suoi frammenti di codice, si sta movimentazione CTRL + V in modo esplicito - non farlo mai! - l'utente potrebbe avere incollato configurato per essere una combinazione di tasti diversa, ad esempio. Ci deve essere un messaggio "Incolla" più ampio dal sistema operativo che puoi gestire. – BrainSlugs83