2011-09-30 2 views
17

Comment puis-je modifier dynamiquement le contenu de ce qui sera collé dans la zone de texte.Modifier le contenu du paste dans la zone de texte

Voici comment je souscris à l'événement:

DataObject.AddPastingHandler (uiTextBox, TextBoxPaste); 

Voici comment je définir le gestionnaire d'événements:

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

    // I can't just do "args.DataObject.SetData (result)" here. 
} 

Répondre

15

Je peux penser à deux façons, dont aucune n'est très attrayante :) Et les deux façons comprennent l'annulation de la commande coller.

La première façon serait d'annuler la commande de collage, puis de calculer à quoi ressemblera le texte après le collage si result a été collé à la place. L'autre façon serait d'annuler la commande coller, de changer le texte dans le Presse-papiers, puis de ré-exécuter le collage. Cela nécessiterait également que vous différiez entre la commande paste réelle et la commande paste invoquée manuellement. Quelque chose comme ça

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

Oui, je pensais aussi à votre première méthode. La deuxième méthode est considérablement pire, puisque vous modifiez le contenu du Presse-papiers. De toute façon, c'est exactement ce que je cherchais, merci! – Dave

+0

Merci pour la réponse. Je veux juste poster une version plus courte de la première méthode (de 9 lignes à 3 lignes): 'int caret = uiTextBox.CaretIndex; uiTextBox.Text = uiTextBox.Text.Insert (uiTextBox.SelectionStart, résultat); uiTextBox.CaretIndex = caret + result.Length; ' – newman

+0

Sender est la zone de texte dans laquelle l'événement paste se produit, donc plutôt que d'avoir à référencer explicitement une zone de texte particulière, vous pouvez simplement lancer l'expéditeur en tant que TextBox (ou autre) . – Will

0

J'utilise VB.net un peu, je l'ai testé cette C# bits, j'ai utilisé un convertisseur parce que je suis boiteux :)

string oClipboard; 

    private void TextBox1_GotFocus(object sender, System.EventArgs e) 
    { 
     oClipboard = Clipboard.GetText(); 
     Clipboard.SetText("foo"); 
    } 

    private void TextBox1_LostFocus(object sender, System.EventArgs e) 
    { 
     Clipboard.SetText(oClipboard); 
    } 

Je place le presse-papiers dans le nouveau texte lorsque le contrôle obtient le focus. Il stocke l'ancienne valeur. Plus tard, lorsque le contrôle perd le focus, le presse-papiers est remis à l'ancienne valeur.

23

Vous ne pouvez pas appeler args.DataObject.SetData (« certaines données ») depuis le DataObject est gelé. Ce que vous pouvez faire est de remplacer le DataObject total:

private void TextBoxPaste(object sender, DataObjectPastingEventArgs e) { 
     string text = (String)e.DataObject.GetData(typeof(String)); 
     DataObject d = new DataObject(); 
     d.SetData(DataFormats.Text, text.Replace(Environment.NewLine, " ")); 
     e.DataObject = d; 
} 
+2

C'est de loin une solution plus élégante –

0

Juste quelques modifications de @ code de Fredrik, depuis que je suis en train à la fois de ses méthodes.

La première est juste une version raccourcie

private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e) 
{ 
    string clipboard = e.DataObject.GetData(typeof(string)) as string; 
    Regex nonNumeric = new System.Text.RegularExpressions.Regex (@"\D"); 
    string result = nonNumeric.Replace(clipboard, string.Empty); 

    int caret = CaretIndex; 
    Text = Text.Substring(0, SelectionStart) + result + 
     Text.Substring(SelectionStart + SelectionLength); 
    CaretIndex = caret + result.Length; 

    e.CancelCommand(); 
} 

et l'autre est mis à jour en gardant le contenu du presse-papiers

private string oldClipboardContent { get; set; } = ""; 
private bool pasteModified { get; set; } = false; 

private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e) 
{ 
    if (pasteModified) 
    { 
     pasteModified = false; 
    } 
    else 
    { 
     pasteModified = true; 

     string text = (string)e.DataObject.GetData(typeof(string)); 
     oldClipboardContent = text; 

     Regex nonNumeric = new System.Text.RegularExpressions.Regex (@"\D"); 
     text = nonNumeric.Replace(text, string.Empty); 
     e.CancelCommand(); 

     Clipboard.SetData(DataFormats.Text, text); 
     ApplicationCommands.Paste.Execute(text, this); 

     Clipboard.SetData(DataFormats.Text, OldClipboardContent); 
     oldClipboardContent = ""; 
    } 
} 

j'utilisais ceux à l'intérieur de mon contrôle personnalisé TextBox, c'est pourquoi je pourrait accéder à TextBox propriétés sans écrire le nom en premier.

Questions connexes