Bonjour,
J'utilise VS2012 avec C# et je découvre Linq to Entities en exploitant la base exemple Chinook (version sqlite).
J'ai mis en place d'un treeview qui déroule :
Artist - Album - Track
Quand j'atteins le dernier niveau (3) j'affiche le nom du "Track" dans un textBox et le Genre dans comboBox afin de pouvoir les modifier.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 private void Init_treeView1() { TreeNode treeNodeRacine; treeNodeRacine=new TreeNode("Racine"); treeView1.Nodes.Add(treeNodeRacine); var treeView1_req = from a in context.Artist orderby a.Album.Count() descending select a; foreach (var artist in treeView1_req) { TreeNode treeArtist; treeArtist = new TreeNode(artist.Name + " (" + artist.Album.Count() + " albums)"); treeNodeRacine.Nodes.Add(treeArtist); var Albums = artist.Album.OrderByDescending(p => p.Track.Count()); foreach (var album in Albums) { TreeNode treeAlbum; treeAlbum = new TreeNode(album.Title + " (" + album.Track.Count() + " tracks)"); treeArtist.Nodes.Add(treeAlbum); foreach (var track in album.Track) { treeAlbum.Nodes.Add(track.TrackId.ToString(),track.Name + " (" + track.Genre.Name.ToString() +" )"); } } } }
Pour se faire, après la sélection du Node je lie ces 2 contrôles aux éléments de l'entité correspondante :
La datasource du comboBox a été préalablement chargée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) { if (treeView1.SelectedNode.Level == 3) // on prend que les entreprises pas la structure { TRACKID = Convert.ToInt64(e.Node.Name); var track = from b in context.Track where b.TrackId == TRACKID select b; try { textBox3.DataBindings.Clear(); comboBox4.DataBindings.Clear(); textBox3.DataBindings.Add(new Binding("Text", track.ToList(), "Name")); comboBox4.DataBindings.Add(new Binding("SelectedValue", track.ToList(), "GenreId", false, DataSourceUpdateMode.OnPropertyChanged)); } catch (Exception ex) { MessageBox.Show("Erreur \n" + ex.Message, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
Ces 2 contrôles sont englobés dans un tabPage. Quand celui-ci est validé je répercute les modifications dans la base de donnée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 private void Init_comboBox4() { var ComboBox4_req = from a in context.Genre orderby a.Name select a; comboBox4.DataSource = ComboBox4_req.ToArray(); comboBox4.DisplayMember = "Name"; comboBox4.ValueMember = "GenreId"; }
Tout ce passe bien pour le textBox mais la mise à jour de la clé étrangère "GenreId" qui est couplée à la combobox ne se fait pas dans la table "Track". En fait elle n'est même pas stockée dans le modèle. Dès que je change d'enregistrement, la valeur initiale de "GenreId" se repositionne. Je cherche en vain de comprendre le phénomène afin de le corriger.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 private void tabPage1_Validated(object sender, EventArgs e) { try { context.SaveChanges(); } catch (Exception ex) { MessageBox.Show("Erreur \n" + ex.Message, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Dans l'évènement "Validating" du combobox c'est bien la valeur modifiée qui apparait, mais dans l'évènement "Validated" c'est la valeur initiale qui réapparait
Afin de contourner le problème j'ai rajouter un peu de code pour faire la mise à jour "à la main" :
Ca permet bien de conserver la valeur modifiée dans le modèle et donc de mettre à jour la base mais je trouve la méthode un peu "crade" ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 private void comboBox4_SelectedValueChanged(object sender, EventArgs e) { if (TRACKID != 0) { try { var req = from a in context.Track where a.TrackId == TRACKID select a; req.First().GenreId = Convert.ToInt64(comboBox4.SelectedValue.ToString()); } catch (Exception ex) { MessageBox.Show("Erreur \n" + ex.Message, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Peut-on faire mieux ou autrement ?
Merci de vos lumières.
Partager