Remplissage spéciale d'une Combobox [Résolu]

Signaler
Messages postés
1182
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
-
Messages postés
1182
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
-
Salut tout le monce,

voila mon pb du jour :
je souhaite remplir une combo ( pas de pb jusque la) à partir d'un dataset et utilisant les display member et value member.
en fait dans ma combo je veux afficher le code et le libelle d'une table civilite ( par exemple "M Monsieur"...)

je fais donc mon select, j'utilise un datareader pour remplir un dataset que j'ai defini avec mes petites mains, en ajoutant une colonne (qui sera utiliser comme displaymember) en plus par rapport a ma table qui à une expression : "CIVCOD + ' ' + CIVLIB" Civcod etant mon champ code de la table civilite et civlib mon libelle de la meme table...

seulement voila a l'affichage c pas beau...
j'ai :
M Monsieur
MME Madame
....

bref ca fait des acordeons...

je me suis dis je remplace l'expression par : "CIVCOD + '\t' + CIVLIB"
seulement voila dans ma combo apparait un carre pas beau...
alors que la meme expression me donne bien un tab dans une listebox....
kkun a une idee ???

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."

23 réponses

Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
ah ba oui forcement moi je suis parti sur des items affectés direct en texte
toi il faut que tu recupère la valeur que tu as mis en tant que DisplayMember, donc la valeur de la colonne "display" si je ne me trompe pas
ce qui transforme
string item = combo.Items[e.Index].ToString();

en
string item = ((DataRowView)combo.Items[e.Index]).Row["display"].ToString();

(de tête)

Cocoricoooooooo !!!!
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
voilà, avec ce code Monsieur, Madame & co sont eux aussi alignés :

private void comboBox_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
if ( e.Index != -1 )
{
ComboBox combo = (ComboBox)sender;
string item = combo.Items[e.Index].ToString();
string debut, fin;

debut = item.Substring(0, item.IndexOf(' '));
fin = item.Substring(item.IndexOf(' ')+1);

// dessin
StringFormat format = new StringFormat();

// fond
SolidBrush brushFond, brushTexte;

// si item sélectionné
if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected )
{
// inversion des couleurs
brushFond = new SolidBrush(e.ForeColor);
brushTexte = new SolidBrush(e.BackColor);
}
else
{
brushFond = new SolidBrush(e.BackColor);
brushTexte = new SolidBrush(e.ForeColor);
}

// fond
e.Graphics.FillRectangle(brushFond, e.Bounds);

// rectangle de sélection si sélection
if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected )
e.DrawFocusRectangle();

// debut
format.Alignment = StringAlignment.Near;
e.Graphics.DrawString(debut, 
e.Font, 
brushTexte, 
e.Bounds, 
format
);
// fin
RectangleF bounds = e.Bounds;
bounds.X = bounds.Width - max_largeur_fin;
e.Graphics.DrawString(fin, 
e.Font, 
brushTexte, 
bounds, 
format
);
}
}

private float max_largeur = 0.0f;
private float max_hauteur = 0.0f;
private float max_largeur_fin = 0.0f;
private const int max_largeur_ajout = 10;

private void comboBox_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)
{
if ( e.Index != -1 )
{
ComboBox combo = (ComboBox)sender;
SizeF temp;

string item = combo.Items[e.Index].ToString();
temp = e.Graphics.MeasureString(item, combo.Font);
if ( temp.Width > max_largeur-max_largeur_ajout )
max_largeur = temp.Width+max_largeur_ajout;
if ( temp.Height > max_hauteur )
max_hauteur = temp.Height;

// mesure de la chaine de fin
string fin = item.Substring(item.IndexOf(' ')+1);
temp = e.Graphics.MeasureString(fin, combo.Font);
if ( temp.Width > max_largeur_fin )
max_largeur_fin = temp.Width;

e.ItemHeight = (int)max_hauteur;
e.ItemWidth = (int)max_largeur;
combo.DropDownWidth = (int)max_largeur;
}
}


Cocoricoooooooo !!!!
Messages postés
1182
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
14
YES !!!!!!!!!!!!!!!!!!!!!!!!!!!

Apres deux petits amenagement au niveau de l'item des deux fonctions c'est pile poil ce que je voulais....

parfait :o)))

		private float max_largeur = 0.0f;
private float max_hauteur = 0.0f;
private float max_largeur_fin = 0.0f;
private const int max_largeur_ajout = 10;

private void cbo_T_CIVILITE_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)
{
if ( e.Index != -1 )
{
ComboBox combo = (ComboBox)sender;
SizeF temp;

System.Data.DataRowView row = (System.Data.DataRowView) combo.Items[e.Index];
string item = row["display"].ToString ();
temp = e.Graphics.MeasureString(item, combo.Font);
if ( temp.Width > max_largeur-max_largeur_ajout )
max_largeur = temp.Width+max_largeur_ajout;
if ( temp.Height > max_hauteur )
max_hauteur = temp.Height;

// mesure de la chaine de fin
string fin = item.Substring(item.IndexOf(' ')+1);
temp = e.Graphics.MeasureString(fin, combo.Font);
if ( temp.Width > max_largeur_fin )
max_largeur_fin = temp.Width;

e.ItemHeight = (int)max_hauteur;
e.ItemWidth = (int)max_largeur;
combo.DropDownWidth = (int)max_largeur;
}
}

private void cbo_T_CIVILITE_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
if ( e.Index != -1 )
{
ComboBox combo = (ComboBox)sender;
System.Data.DataRowView row = (System.Data.DataRowView) combo.Items[e.Index];
string item = row["display"].ToString ();
string debut, fin;

debut = item.Substring(0, item.IndexOf(' '));
fin = item.Substring(item.IndexOf(' ')+1);

// dessin
StringFormat format = new StringFormat();

// fond
SolidBrush brushFond, brushTexte;

// si item sélectionné
if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected )
{
// inversion des couleurs
brushFond = new SolidBrush(e.ForeColor);
brushTexte = new SolidBrush(e.BackColor);
}
else
{
brushFond = new SolidBrush(e.BackColor);
brushTexte = new SolidBrush(e.ForeColor);
}

// fond
e.Graphics.FillRectangle(brushFond, e.Bounds);

// rectangle de sélection si sélection
if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected )
e.DrawFocusRectangle();

// debut
format.Alignment = StringAlignment.Near;
e.Graphics.DrawString(debut, 
e.Font, 
brushTexte, 
e.Bounds, 
format
);
// fin
RectangleF bounds = e.Bounds;
bounds.X = bounds.Width - max_largeur_fin;
e.Graphics.DrawString(fin, 
e.Font, 
brushTexte, 
bounds, 
format
);
}
}


merci monsieur Coq :big)
y a plus qu'a essayer de comprendre tout ca :clown)

:-p

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
1182
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
14
Petite précision, j'ai déja essayer d'utiliser une police style courier new et de rajouter des espaces derrieres mon code (de taille max 10) pour qu'a l'affichage ca ressemble a kkchose...mais bon faut aimer la police courier new...

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
Met toi en DrawMode = OwnerDrawFixed et fait un truc de ce genre :

private void comboBox_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)
{
ComboBox combo = (ComboBox)sender;
float max_largeur = 0.0f;
float max_hauteur = 0.0f;
SizeF temp;
foreach ( string item in combo.Items )
{
temp = e.Graphics.MeasureString(item, combo.Font);
if ( temp.Width > max_largeur )
max_largeur = temp.Width;
if ( temp.Height > max_hauteur )
max_hauteur = temp.Height;
}

// ajout de 100 pixels en plus au max
max_largeur += 10;

e.ItemHeight = (int)max_hauteur;
e.ItemWidth = (int)max_largeur;
}


private void comboBox_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
if ( e.Index != -1 )
{
ComboBox combo = (ComboBox)sender;
string item = combo.Items[e.Index].ToString();
string debut, fin;

debut = item.Substring(0, item.IndexOf(' '));
fin = item.Substring(item.IndexOf(' ')+1);

// dessin
StringFormat format = new StringFormat();

// fond
SolidBrush brushFond, brushTexte;

// si item sélectionné
if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected )
{
// inversion des couleurs
brushFond = new SolidBrush(e.ForeColor);
brushTexte = new SolidBrush(e.BackColor);
}
else
{
brushFond = new SolidBrush(e.BackColor);
brushTexte = new SolidBrush(e.ForeColor);
}

// fond
e.Graphics.FillRectangle(brushFond, e.Bounds);

// rectangle de sélection si sélection
if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected )
e.DrawFocusRectangle();

// debut
format.Alignment = StringAlignment.Near;
e.Graphics.DrawString(debut, 
e.Font, 
brushTexte, 
e.Bounds, 
format
);
// fin
format.Alignment = StringAlignment.Far;
e.Graphics.DrawString(fin, 
e.Font, 
brushTexte, 
e.Bounds, 
format
);
}
}


je te laisse changer les détails

Cocoricoooooooo !!!!
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
pas bien réveillé moi ce matin
Mon MeasureItem ne servait à rien...

private float max_largeur = 0.0f;
private float max_hauteur = 0.0f;
private const int max_largeur_ajout = 10;

private void comboBox_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)
{
if ( e.Index != -1 )
{
ComboBox combo = (ComboBox)sender;
SizeF temp;

string item = combo.Items[e.Index].ToString();
temp = e.Graphics.MeasureString(item, combo.Font);
if ( temp.Width > max_largeur-max_largeur_ajout )
max_largeur = temp.Width+max_largeur_ajout;
if ( temp.Height > max_hauteur )
max_hauteur = temp.Height;

e.ItemHeight = (int)max_hauteur;
e.ItemWidth = (int)max_largeur;
combo.DropDownWidth = (int)max_largeur;
}
}


devrait mieux fontionner

Cocoricoooooooo !!!!
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
ah j'oubliais : met toi en OwnerDrawVariable

Cocoricoooooooo !!!!
Messages postés
1182
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
14
houla....

comment je me met en ownerdrawvariable ???

et si tu as un peu de temps peu tu m'expliquer les fonctions de ces 2 evenements...

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
tu affectes cette valeur à la propriété DrawMode du ComboBox en question

MeasureItem permet de spécifier les dimensions de dessin des item (déclenché une seule fois pour chaque item)

DrawItem est déclenché à chaque fois qu'un item doit etre dessiné

Cocoricoooooooo !!!!
Messages postés
1182
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
14
ok...
j'ai une exception de levee...
le control est un control que j'herite de combobox stocker dans une dll dans drawItem j'ai remplacé :

debut = item.Substring(0, item.IndexOf(' '));
fin = item.Substring(item.IndexOf(' ')+1);

par

debut = item.Substring(0, item.IndexOf('\t'));
fin = item.Substring(item.IndexOf('\t')+1);


j'obtiens l'exeption suivante quand je clique sur le combo :
Informations supplémentaires : La longueur ne peut pas être inférieure à zéro.
sur le debut = .....

??????

par contre avant de faire quoi que ce soit il m'affiche à nouveau un chtit carre...

:-p

funaize c lourd qd meme pour un petit tab entre 2 champs....

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
ba en fait je me suis basé sur des items de ce genre
CIVCOD + " " + CIVLIB

Cocoricoooooooo !!!!
Messages postés
1182
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
14
bon voila le code total :

using System;
using System.Windows.Forms;
using System.Drawing ;
using ToolDataBase;
using System.ComponentModel ;
using System.Data;
using System.Threading ;

namespace Tools
{
/// <summary>
/// Description résumée de cbo_T_CIVILITE.
/// </summary>
public class cbo_T_CIVILITE	: System.Windows.Forms.ComboBox 
{
private int _index_bdd;
private string _ConnectionString;
private Thread thread = null;

public cbo_T_CIVILITE()
{
Font Font_Text = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));

this.Font = Font_Text;
this.DrawItem +=new DrawItemEventHandler(cbo_T_CIVILITE_DrawItem);
this.MeasureItem += new MeasureItemEventHandler(cbo_T_CIVILITE_MeasureItem);
this.DrawMode = DrawMode.OwnerDrawVariable;

}
/// <summary>
/// Index de la base de donnée à Utiliser	(0 : SQL SERVEUR 1 : Mysql)
/// </summary>
[Description("Index de base de données à utiliser (0 : SQL SERVEUR 1 : Mysql)")]
public int Index_Bdd
{
get
{
 return _index_bdd;
}
set
{
_index_bdd = value;
}
}

/// <summary>
/// Chaine de connexion à la base de donnée
/// </summary>
[Description("Chaine de connexion à la base de donnée")]
public string ConnectionString
{
get
{
return _ConnectionString;
}
set
{
_ConnectionString = value;
}
}

/// <summary>
/// Fonction qui va remplir la Combo Box
/// </summary>
public void Rempli_Cbo()
{
thread = new Thread(new ThreadStart(_Rempli_Cbo));
thread.Start();
}

private void _Rempli_Cbo()
{
try
{
ToolConnection MaConnect = new ToolConnection(this.Index_Bdd , this.ConnectionString );
ToolCommand MaCmd = new ToolCommand(this.Index_Bdd,"EXEC T_CIVILITE_SELECT",MaConnect);
DataSet ds = new DataSet();
ds.Tables.Add("T_CIVILITE");
ds.Tables["T_CIVILITE"].Columns.Add("civnum",typeof(Decimal));
ds.Tables["T_CIVILITE"].Columns.Add("civcod",typeof(string));
ds.Tables["T_CIVILITE"].Columns.Add("civlib",typeof(string));
ds.Tables["T_CIVILITE"].Columns.Add("display",typeof(string), "civcod +' '+ civlib");

MaConnect.Open();
System.Data.IDataReader Monreader = MaCmd.ExecuteReader ();
while(Monreader.Read())
{
DataRow row = ds.Tables["T_CIVILITE"].NewRow();
row.BeginEdit ();
row["civnum"] = Monreader.GetDecimal(0);
row["civcod"] = Monreader.GetString(1);
row["civlib"] = Monreader.GetString(2);
row.EndEdit();
ds.Tables["T_CIVILITE"].Rows.Add(row);
}
Monreader.Close();
MaConnect.Close();
this.DataSource = ds.Tables["T_CIVILITE"];
this.DisplayMember = "display";
this.ValueMember = "civnum";

}
catch(Exception xcp)
{
MessageBox.Show(xcp.Message.ToString());
}
}

/// <summary>
/// Fonction qui va remplir la Combo Box
/// </summary>
/// (int) Index de base (0 : SQL SERVEUR, 1 : Mysql)

/// (string) Chaine de Connection

public void Rempli_Cbo(int Index_Bdd, string ConnectionString)
{
this.Index_Bdd = Index_Bdd ;
this.ConnectionString = ConnectionString;
thread = new Thread(new ThreadStart(_Rempli_Cbo));
thread.Start();
}

private float max_largeur = 0.0f;
private float max_hauteur = 0.0f;
private const int max_largeur_ajout = 10;

private void cbo_T_CIVILITE_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)
{
if ( e.Index != -1 )
{
ComboBox combo = (ComboBox)sender;
SizeF temp;

string item = combo.Items[e.Index].ToString();
temp = e.Graphics.MeasureString(item, combo.Font);
if ( temp.Width > max_largeur-max_largeur_ajout )
max_largeur = temp.Width+max_largeur_ajout;
if ( temp.Height > max_hauteur )
max_hauteur = temp.Height;

e.ItemHeight = (int)max_hauteur;
e.ItemWidth = (int)max_largeur;
combo.DropDownWidth = (int)max_largeur;
}
}

private void cbo_T_CIVILITE_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
if ( e.Index != -1 )
{
ComboBox combo = (ComboBox)sender;
string item = combo.Items[e.Index].ToString();
string debut, fin;

debut = item.Substring(0, item.IndexOf(' '));
fin = item.Substring(item.IndexOf(' ')+1);

// dessin
StringFormat format = new StringFormat();

// fond
SolidBrush brushFond, brushTexte;

// si item sélectionné
if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected )
{
// inversion des couleurs
brushFond = new SolidBrush(e.ForeColor);
brushTexte = new SolidBrush(e.BackColor);
}
else
{
brushFond = new SolidBrush(e.BackColor);
brushTexte = new SolidBrush(e.ForeColor);
}

// fond
e.Graphics.FillRectangle(brushFond, e.Bounds);

// rectangle de sélection si sélection
if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected )
e.DrawFocusRectangle();

// debut
format.Alignment = StringAlignment.Near;
e.Graphics.DrawString(debut, 
e.Font, 
brushTexte, 
e.Bounds, 
format
);
// fin
format.Alignment = StringAlignment.Far;
e.Graphics.DrawString(fin, 
e.Font, 
brushTexte, 
e.Bounds, 
format
);
}
}

}
}



j'ai toujours la meme exeption meme en changeant l'expression de ma colonne
Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
donc c'est que la methode IndexOf ne trouve pas le caractère espace dans la chaine, et retourne -1

Cocoricoooooooo !!!!
Messages postés
1182
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
14
ben oui c space parce que le premier text qui apparait est bien : "M Monsieur", y a donc bien des espaces dedans ....

???

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
ba il ne te reste plus qu'a mettre des points d'arret et verifier les valeurs pour trouver ce qui cloche

Cocoricoooooooo !!!!
Messages postés
1182
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
14
en fait dans l'objet item j'ai
item="System.Data.DataRowView";
alors forcement...le ' ' il le trouve pas :o))

je continue mes recherches...

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
1182
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
14
ca progresse j'ai modifier le code :
System.Data.DataRowView row = (System.Data.DataRowView) combo.Items[e.Index];
string item = row["display"].ToString ();


plus d'exeption mais j'ai toujours des accordeons..
donc je cherche toujours :o))

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
erf, me suis encore fait avoir ^^

toujours l'accordeon ?
mais tu as bien un grand espace qui c'est placé entre M et Monsieur non ?
parce que si par accordéon tu désignes le fait que les chaines "fin" ne sont pas alignées à gauche c'est "normal", je les desine en les alignant à droite

Cocoricoooooooo !!!!
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
oui y'a de l'amenagement à faire c'est sur, je me suis pas vraiment occupé des détails ^^

Cocoricoooooooo !!!!
Messages postés
346
Date d'inscription
lundi 8 septembre 2003
Statut
Membre
Dernière intervention
3 septembre 2007
3
Et ca ca marchait bien sans faire de la quatrième colonne une colonne calculée ( et encore en expression ca doit marcher

ds.Tables.Add("T_CIVILITE");
ds.Tables["T_CIVILITE"].Columns.Add("civnum",typeof(Decimal));
ds.Tables["T_CIVILITE"].Columns.Add("civcod",typeof(string));
ds.Tables["T_CIVILITE"].Columns.Add("civlib",typeof(string));
ds.Tables["T_CIVILITE"].Columns.Add("display",typeof(string));

string temp;
MaConnect.Open();
System.Data.IDataReader Monreader = MaCmd.ExecuteReader ();
while(Monreader.Read())
{
DataRow row = ds.Tables["T_CIVILITE"].NewRow();
row.BeginEdit ();
row["civnum"] = Monreader.GetDecimal(0);
row["civcod"] = Monreader.GetString(1);
row["civlib"] = Monreader.GetString(2);
temp = row["civnum"] +" ";
row["dsiplay"= temp.substring(temp,0,5) + row["civlib"];
row.EndEdit();
ds.Tables["T_CIVILITE"].Rows.Add(row);
}
Monreader.Close();

enfin pi etre que non