FAQ C++/CLI et VC++.NetConsultez toutes les FAQ

Nombre d'auteurs : 29, nombre de questions : 248, création le 22 février 2013 

 
OuvrirSommaireIntéraction du C++/CLI avec le framework .NetWinFormsTextBox

On se sert des événements de touches. Ils se produisent lorsque le TextBox a le focus dans l'ordre suivant :

  • KeyDown :
    Une touche a été enfoncée
  • KeyPress :
    Déclenché si la touche enfoncée représente un caractère. (Il n'est pas déclenché pour les touches F1, F2 par exemple)
  • KeyUp :
    Une touche a été relâchée

Voici un exemple d'utilisation.
Créer un projet WinForm.
Ajouter deux TextBox à la form principale de votre projet.
Le code suivant utilise une form nommée Form1, et deux TextBox nommés textBox1 et textBox2.
Toutes les touches frappées sur le textBox1 se répercutent sur textBox2.

 
Sélectionnez

private: System::Void button1_KeyUp(System::Object^  sender, System::Windows::Forms::KeyEventArgs^  e) 
{
	//Exemple après l'appui de la touche "Enter"
	if (e->KeyCode == Keys::Enter)
	{
		//Arrêter la capture d'événements clavier sur le contrôle
		this->button1->KeyUp -= gcnew KeyEventHandler(this, &Form1::button1_KeyUp);
		//Traitements longs
 
		//Reprendre la capture d'événements clavier sur le contrôle
		this->button1->KeyUp += gcnew KeyEventHandler(this, &Form1::button1_KeyUp);
	}
}
private: System::Void textBox1_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) 
{
	// On affiche tous les caractères imprimables
	if (!Char::IsControl(e->KeyChar))
		textBox2->Text = textBox1->Text->Substring(0, textBox1->SelectionStart) +
			e->KeyChar + textBox1->Text->Substring(textBox1->SelectionStart + textBox1->SelectionLength);
}
private: System::Void textBox1_KeyDown(System::Object^  sender, System::Windows::Forms::KeyEventArgs^  e) 
{
	// Gestion Touche Back
	if (e->KeyCode == Keys::Back && textBox1->Text->Length > 0)
	{
		if (textBox1->SelectionLength > 0)
		{
			// Suppression sélection
			textBox2->Text = textBox1->Text->Substring(0, textBox1->SelectionStart) + 
					textBox1->Text->Substring(textBox1->SelectionStart + textBox1->SelectionLength);
		}
		else if (textBox1->SelectionStart > 0)
		{
			// Suppression caractère précédant le curseur
			if (textBox1->SelectionStart == textBox1->Text->Length)
				textBox2->Text = textBox1->Text->Substring(0, textBox1->Text->Length-1);
			else
				textBox2->Text = textBox1->Text->Substring(0, textBox1->SelectionStart-1) + 
							textBox1->Text->Substring(textBox1->SelectionStart +
							textBox1->SelectionLength);
		}
	}
	// Touche Delete (suppr)
	else if (e->KeyCode == Keys::Delete &&  textBox1->Text->Length > 0)
	{
		// Le curseur est en fin de chaîne
		if (textBox1->SelectionStart == textBox1->Text->Length)
		{
			// Suppression dernier caractère par Shift+Del
			if (e->Shift) 
				textBox2->Text = textBox1->Text->Substring(0, textBox1->Text->Length-1);
		}
		else
		{
			// On prend tous les caractères à gauche du curseur
			textBox2->Text = textBox1->Text->Substring(0, textBox1->SelectionStart);
			if (textBox1->SelectionLength != 0)
				// Suppression de la selection
				textBox2->AppendText(textBox1->Text->Substring(textBox1->SelectionStart +
						textBox1->SelectionLength));
			else
			{
				// Si la touche control est enfoncée, tous les caractères
				// à droite du curseur seront supprimés. Sinon on en supprime
				// un seul
				if (!e->Control)
					textBox2->Text = textBox1->Text->Substring(0, textBox1->SelectionStart) +
							textBox1->Text->Substring(textBox1->SelectionStart+1);
			}
		}
	}
	// Coller (Ctrl+V) ou (Shift+insert).
	else if ((e->Shift && e->KeyCode == Keys::Insert) || (e->Control && e->KeyCode == Keys::V))
	{
		// Données dans presse papier
		IDataObject ^cpdata = Clipboard::GetDataObject();
		// Test si cpdata contient du texte
		if (cpdata != nullptr && cpdata->GetDataPresent(String::Empty->GetType()))
		{
			String ^data = cpdata->GetData(String::Empty->GetType())->ToString();
			bool print = false;
			// Gestion caractères non imprimables (comme les tabulations par exemple)
			for (int i=0; i<data->Length-1; i++)
			{
				if (Char::IsControl(data, i) && print)
				{
					data = data->Substring(0, i);
					break;
				}
				else if (!Char::IsControl(data, i) && !print)
					print = true;
			}
			textBox2->Text = textBox1->Text->Substring(0, textBox1->SelectionStart) +
						data + textBox1->Text->Substring(textBox1->SelectionStart + textBox1->SelectionLength);
		}
	}
}				
				
Créé le 9 mai 2006  par nico-pyright(c), abelman

On se sert de l'événement KeyPress pour intercepter les caractères entrés dans le TextBox.
La propriété Handled de la classe KeyPressEventArgs indique à l'application ce qu'il faut faire du caractère intercepté.
Si elle vaut false, le traitement par défaut du caractère (l'affichage pour les caractères imprimables) est appliqué.
Si elle vaut true, c'est votre code qui décide ce qu'il faut faire du caractère. Si vous ne faites rien, il ne sera pas affiché. Sa valeur par défaut est false.
Exemple simple :

 
Sélectionnez

private: System::Void textBox1_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) 
{
	if (!Char::IsDigit(e->KeyChar))
	// Tous les caractères non numériques ne sont pas traités sur le TextBox.
		e->Handled = true;		 
}			
				

Remarque: Avec ce code, des touches générant un caractère non imprimable (comme la touche BACK) n'auront aucun effet sur le textbox.
Si vous voulez faire un véritable contrôle TexBox numérique, vous devez en tenir compte, gérer le copier-coller CTRL+C et SHIFT+INS avec l'événement KeyDown, et aussi avec le clic droit (menu contextuel coller) sur la souris.

Créé le 9 mai 2006  par nico-pyright(c), abelman

Dans le Validating du ou des TextBox : Pour des nombres Réels :

 
Sélectionnez

private: System::Void textBox1_Validating(System::Object^  sender, System::ComponentModel::CancelEventArgs^  e) 
{
	if (sender->GetType() == TextBox::typeid)
	{
		TextBox ^T = safe_cast<TextBox ^>(sender);
		try
		{
			Double::Parse(T->Text);
			epErrorProvider->SetError(T, "");
		}
		catch (ArgumentNullException^)
		{
			epErrorProvider->SetError(T, "La case ne peut être vide !");
			T->SelectAll();
			e->Cancel = true;
		}
		catch (OverflowException^)
		{
			epErrorProvider->SetError(T, "Le nombre est trop grand !");
			T->SelectAll();
			e->Cancel = true;
		}
		catch (FormatException^)
		{
			epErrorProvider->SetError(T, "Le format n'est pas correct");
			T->SelectAll();
			e->Cancel = true;
		}
	}
}
				

Pour les nombres décimaux :

 
Sélectionnez

private void TextBox_Validating(object sender, CancelEventArgs e)
{
     if (sender->GetType() == TextBox::typeid)
     {
        TextBox ^T = safe_cast<TextBox ^>(sender);
        try
        {
           Decimal::Parse(T->Text);
           epErrorProvider->SetError(T, "");
        }
        catch (ArgumentNullException^)
        {
           epErrorProvider->SetError(T, "La case ne peut être vide !");
           T->SelectAll();
           e->Cancel = true;
        }
        catch (OverflowException^)
        {
           epErrorProvider->SetError(T, "Le nombre est trop grand !");
           T->SelectAll();
           e->Cancel = true;
        }
        catch (FormatException^)
        {
           epErrorProvider->SetError(T, "Le format n'est pas correct");
           T->SelectAll();
           e->Cancel = true;
        }
     }
}				
				

N'oubliez pas de mettre le bon caractère comme séparateur decimal :

 
Sélectionnez

private: System::Void textBox1_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) 
 {
	// stoque le séparateur décimal du système
	wchar_t Separateur = System::Globalization::CultureInfo::CurrentCulture->NumberFormat->NumberDecimalSeparator[0];
	// dans le cas de l'ecriture d'un séparateur
	if ((e->KeyChar == '.') || (e->KeyChar == ','))
	{
		// Force l'ecriture du bon séparateur
		e->KeyChar = Separateur;
	}
 }				
				

Pour des nombres Entiers :

 
Sélectionnez

private void TextBox_Validating(object sender, CancelEventArgs e)
{
     if (sender->GetType() == TextBox::typeid)
     {
		TextBox ^T = safe_cast<TextBox ^>(sender);
		try
		{
			Integer::Parse(T->Text);
			epErrorProvider->SetError(T, "");
		}
		catch (ArgumentNullException^)
		{
			epErrorProvider->SetError(T, "La case ne peut être vide !");
			T->SelectAll();
			e->Cancel = true;
		}
		catch (OverflowException^)
		{
			epErrorProvider->SetError(T, "Le nombre est trop grand !");
			T->SelectAll();
			e->Cancel = true;
		}
		catch (FormatException^)
		{
			epErrorProvider->SetError(T, "Le format n'est pas correct");
			T->SelectAll();
			e->Cancel = true;
		}
	}
}
         	
Mis à jour le 12 juillet 2006  par nico-pyright(c), doccpu

Dans le Validating du ou des TextBox, en utilisant la classe System::Text::RegularExpressions :

 
Sélectionnez

private: System::Void textBox1_Validating(System::Object^  sender, System::ComponentModel::CancelEventArgs^  e) 
 {
	TextBox ^ txtChamp = safe_cast<TextBox^>(sender);
	Regex ^rexValideur = gcnew Regex("expression");
	if(rexValideur->IsMatch(txtChamp->Text))
	{
		epErrorProvider->SetError(txtChamp, "");
	}
	else
	{
		epErrorProvider->SetError(txtChamp, "Valeur du champ invalide.");
		e->Cancel = true;
	}
}
				

Il faut ensuite remplacer expression par une chaîne de caractère représentant une expression régulière. Cette méthode est plus recommandée que les try{}catch{} car ceux-ci utilisent beaucoup plus de ressources.

Créé le 9 mai 2006  par nico-pyright(c), efficks

La classe TextBox donne la possibilité de compléter automatiquement les saisies de l'utilisateur… Un peu comme ce que fait déjà votre navigateur.

Pour cela, vous devez utiliser la collection AutoCompleteCustomSource pour spécifier la liste des valeurs que le Textbox pourra proposer.

 
Sélectionnez

// Activer l'autocompletion
textBoxRecherche->AutoCompleteSource = AutoCompleteSource::CustomSource;
textBoxRecherche->AutoCompleteCustomSource->AddRange(gcnew array<String^>{"Chat", "Cheval", "Chien"});
      

En plus de cela, il est possible de préciser comment le Textbox doit afficher les propositions : Dans une liste (Suggest), directement dans le textbox (Append) ou un mix des 2 solutions précédentes (SuggestAppend).

 
Sélectionnez
textBoxRecherche->AutoCompleteMode = AutoCompleteMode::SuggestAppend;
      
Créé le 27 mars 2007  par Jérôme Lambert

Quand on rajoute du texte à un textbox multiligne avec, par exemple :

 
Sélectionnez
for (int i = 0 ; i < 100 ; i++)
	textBox1->Text += "abc" + Convert::ToString(i) + Environment::NewLine;

le texte s'ajoute bien, mais pour peu que la longueur du texte dépasse la zone visible, on ne voit pas la fin du texte comme il est souvent d'usage.
Pour y remédier, on peut utiliser ces deux lignes de code pour renvoyer le curseur à la fin et provoquer le défilement jusqu'à celui-ci.

 
Sélectionnez
textBox1->SelectionStart = textBox1->TextLength;
textBox1->ScrollToCaret();

On peut aussi envisager de mettre le focus sur le textbox si besoin :

 
Sélectionnez

textBox1->Focus();
Créé le 20 novembre 2007  par nico-pyright(c)
  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006-2007 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.