Hello, en tant que debutant je me lance a ecrire un programme.
Ce programme (qui n'est pas fini) est une sorte de calendrier, mais il affichera les depenses, et peut etre eventuellement aussi des rendez vous comme un calendrier normal.
J'utilise une photo qui, en backgroundimage du Form principal, montre tous les jours de l'année ainsi que les mois.
Chaque depense, par exemple "Mortgage" est representé par un label, legerement modifiée pour obtenir un rectangle de couleur de 10pixel sur 10, sans text. Chaque label ajoute un control au Form afin de generer des evenements comme MouseEnter (qui a pour but d'afficher les details de la depense en question) ou encore MouseClick (qui permet d'ouvrir une autre Form pour pouvoir modifier la depense concernée).
Toutes les données sont stockées dans un fichier xml externe.
Viens le probleme mais avant j'explique encore un peu ma demarche;
Si je veux afficher l'année 2012 et ses depenses, alors je retire tous les controls de 2013 creé auparavant en faisant
Ensuite je change l'image de fond par une autre correspondant a 2012 puis je relance les methodes de recherche et d'affichage des depenses 2012 trouvées dans le xml.
Tout marche correctement.
Maintenant, le probleme est quand je veux modifier une depense, donc quand je click sur un rectangle correspondant. J'ouvre une autre Form en passant les valeurs actuelles dans des textbox etc.. (au passage je ne suis pas sur d'utiliser la meilleur facon pour passer les valeurs, En fait losrque ma sourie entre dans la depense et donc declenche le MouseEnter, j'en profite pour copier les valeurs dans des variables globales, que je rappellerai depuis mon evenement MouseClick, et passerai en parametre dans une methode de la Formfille).
Bref je parviens a modifier mes valeurs et a sauvegarder mon xml de retour dans ma form principal, du coup je relance le processus de trouver dans mon xml les depenses de 2013, et relance le processus de creer les labels (ainsi que les controls) tout comme le programme fait a sa premiere excecution. Sauf que la, la depense modifer (changée de date par example) ne bouge pas et reste a la place ou il etait avant la modification ... !!
J'ai pourtant bien le xml sauvé avant la relecture.. et en debug je vois bien qu'il lit la bonne nouvelle date, mais rien ne se passe juste au niveau du display.
le bout de code suivant est ma methode dans la Form proncipale pour trouver les depenses correspondantes a l'année et a afficher les labels et controls correspondants
private void ProceedDisplay()
{
XmlDocument myDoc = new XmlDocument();
myDoc.Load(dataFile);
ControlsToRemove = 0;
// Reset the table containing the rectangle positions
ResetYearTablePositions();
// Get the type of what to display; "Bills" or "Garantees"
string xPathExp = comboBoxPrimary.Text;
// Select the Node pointed just above
XmlNode xNode = myDoc.SelectSingleNode("//Datas/" + xPathExp);
// read the Year displayed in the label
string ActiveYear = labelYear.Text;
// search for all Node containing an argument "Year" which is equal to the label.text read just above
xPathExp = "//*[@BillYear='" + ActiveYear + "']";
// get a list of all the nodes which match the research just above
XmlNodeList xNodes = myDoc.SelectNodes(xPathExp);
int OriginalControls = this.Controls.Count;
IndexControlsToRemove = OriginalControls;
int i;
for (i = 0; i < xNodes.Count; i++)
{
Bill CurrentBill = new Bill();
CurrentBill.ID = Convert.ToInt32(xNodes[i].Attributes[0].InnerText);
CurrentBill.Day = xNodes[i].Attributes[1].InnerText;
CurrentBill.Month = xNodes[i].Attributes[2].InnerText;
CurrentBill.Year = Convert.ToInt32(xNodes[i].Attributes[3].InnerText);
CurrentBill.Amount = Convert.ToInt32(xNodes[i].Attributes[4].InnerText);
CurrentBill.Notes = xNodes[i].Attributes[7].InnerText;
CurrentBill.Color = xNodes[i].ParentNode.PreviousSibling.InnerText;
int Position = AttributePosition(CurrentBill.Day, CurrentBill.Month, CurrentBill.Year);
DrawRectangle(Convert.ToInt32(CurrentBill.Day), Convert.ToInt32(CurrentBill.Month), CurrentBill.ID, Position, CurrentBill.Color);
}
ControlsToRemove = this.Controls.Count - OriginalControls;
}
la methode DrawRectangle est la suivante
public void DrawRectangle(int Day, int Month, int ID, int Position, string ParaColor)
{
Month = RectX(Month);
Month = Month + (13 * (Position));
Day = RectY(Day);
Label lbl = new Label();
lbl.Name = ID.ToString();
lbl.Top = Day;
lbl.Left = Month;
if (ParaColor "Black") lbl.BackColor Color.Black;
else if (ParaColor "Green") lbl.BackColor Color.Green;
else if (ParaColor "Red") lbl.BackColor Color.Red;
else if (ParaColor "Yellow") lbl.BackColor Color.Yellow;
lbl.Size = new System.Drawing.Size(10, 10);
lbl.MouseEnter += lbl_MouseEnter;
lbl.Click += lbl_Click;
lbl.MouseLeave += lbl_MouseLeave;
this.Controls.Add(lbl);
}
la methode de la form mere, pour metre a jour les données apres avoir été modifier dans la form fille est la suivante
public void UpdateValuesFromEditPayment(int DayUpdated, int MonthUpdated, int YearUpdated, int AmountUpdated, string NotesUpdated, int IDUpdated)
{
XmlDocument myDoc = new XmlDocument();
myDoc.Load(dataFile);
string xPathExp = "//*[@ID=" + IDUpdated.ToString() + "]";
XmlNode xNode = myDoc.SelectSingleNode(xPathExp);
if (DayUpdated.ToString().Length < 2) xNode.Attributes[1].InnerText = "0" + DayUpdated.ToString();
else xNode.Attributes[1].InnerText = DayUpdated.ToString();
if (MonthUpdated.ToString().Length < 2) xNode.Attributes[2].InnerText = "0" + MonthUpdated.ToString();
else xNode.Attributes[2].InnerText = MonthUpdated.ToString();
xNode.Attributes[3].InnerText = YearUpdated.ToString();
xNode.Attributes[4].InnerText = AmountUpdated.ToString();
xNode.Attributes[7].InnerText = NotesUpdated;
myDoc.Save(dataFile);
myDoc.Load(dataFile);
RemoveOldRectangles();
ProceedDisplay();
}
et la methode de la Form mere MouseEnter, lorsque la sourie Entre une depense affichée
Whismeril
Messages postés18988Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention26 mars 2024654 25 févr. 2013 à 14:27
Bonjour
Chaque label ajoute un control au Form afin de generer des evenements comme MouseEnter
un label est déjà un controle qui peut générer des évenements, je ne comprends pas ta phrase du coup.
au passage je ne suis pas sur d'utiliser la meilleur facon pour passer les valeurs, En fait losrque ma sourie entre dans la depense et donc declenche le MouseEnter, j'en profite pour copier les valeurs dans des variables globales, que je rappellerai depuis mon evenement MouseClick, et passerai en parametre dans une methode de la Formfille
Il n'est pas conseillé en C# d'utiliser des variables globales (je ne sais plus trop pourquoi). Ce serait peut être plus pratique de charger tout ton xml dans un contenant de donnée (list<T> par exemple) et ensuite de gérer les données via LinQ, mais c'est à toi de voir.
Chaque label ajoute un control au Form afin de generer des evenements comme MouseEnter
oui je veux dire que des que j'ai la commande
this.Controls.Add(lbl);
alors mon control est ajouté, je ne fais rien d'autre.
Il n'est pas conseillé en C# d'utiliser des variables globales (je ne sais plus trop pourquoi)
Je pense que les globales ne sont pas trop aimées car d'une elles prennent de la place (surtout si elle sont copiées en parametre par valeur a chaque fois) et aussi parce que je pense que le but de la POO est de faire des Class reutilisable, et si j'utilise des Globales je pourrai pas trop reutiliser mes Class dans un autre programme. Enfin c'est ce dont je pense mais je peux me tromper.
Ce serait peut être plus pratique de charger tout ton xml dans un contenant de donnée (list<T> par exemple) et ensuite de gérer les données via LinQ, mais c'est à toi de voir.
Je pensais aussi a charger toutes mes données du xml en memoire et travailler avec la memoire plutot que d'acceder a un fichier externe, mais je pensais que point de vus memoire utilisé ca pourrait devenir gourmand... mais je vais regarder ca de plus pres.
Aussi le fait que je decouvre pas mal de trucs alors je veux pas trop m'embrouiller avec des choses nouvelles.
Je vois toujours mes anciens Controls, pourtant en debug je vois bien qu'ils sont retirés de la list "this.Controls"
Mais ils restent a l'ecran. Pire ils declenchent toujours les "MouseEnter"
je pense que j'ai trouvé et je pense que c'est une erreur de debutant ! donc mes excuses si tu as passé du temps pour une telle betise...
quand j'ouvrais la Form fille, je ne fermais pas la Form mere, du coup elle gardait les meme affichages (ne me demande pas pourquoi...)
si je la cache avec this.hide(); avant d'appeller la Form fille, et la rappelle avec Form1.show(); quand je ferme ma Form fille
alors mon affichage est mis a jour
maintenant, y aurait-il moyen de laisser la FormMere ouverte pendant que la FormFille est au premier plan ?
car ca fait bizarre de la chacher totalement et ouvrir une petite fenetre a la place ?
Whismeril
Messages postés18988Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention26 mars 2024654 25 févr. 2013 à 22:30
Houla j'ai raté des épisodes!
Recrer une instance n'est pas bon, du coup tu en as deux et ça doit être ça qui te mets la garouille.
Pour le passage de tes valeurs, dans les commentaires du tuto que tu as mis en lien, il y a l'adresse d'un code de bidou.
C'est une méthode qui correspondrait bien a ton utilisation (enfin je pense).
En gros, de form1 vers form2, tu passes les données paramètres du contructeur comme pour une méthode.
Avant d'afficher form2 (.show()), tu t'abonnes a un événement de form2.
Dans form2 tu crées un événement (genre donneesmiseajour) qui par l'intermédiaire d'un delegate ( en gros un modèle de signature de méthode) te permets le passage de valeur à un abonné.
Dans le bouton saveandclose, tu générés l'événement avec les paramètres et tu fermes.
Dans form1 la méthode abonnée récupère les donnees et tout baigne!
Test son code et si tu as des questions n'hésite pas.
Je le connais bien, il m'a servit quand j'ai débuté