Bonjour le Forum ^^
Je reviens cette fois pour des conseils de conception.
Le projet que je réalise est une application de comparaison entre 2 personnages pour un jeu.
Chaque personnage a donc des caracteristiques propres, pour simplifier je dit juste son niveau (Level), son métier principal (MainJob).
Chacun peut s'equiper (weapons, head, body, hands, etc...) à l'aide de comboboxs. Les items de ces comboboxs proviennent d'une BDD Access que j'ai importée au préalable dans un DataSet.
Pour en venir au problème, je ne prendrai pour simplifier que les combobox MainWeapon1 et SubWeapon1.
La DataTable "Weapon" est composée des colonnes "Names" (clé primaire), "Level", "Rare Tag", "Equippable Jobs", etc... lesquelles seront utilisées pour le filtrage.
(la colonne "Rare Tag" est une colonne de checkboxs booléennes)
(la colonne "Equippable Jobs" est une colonne type Textbox où l'utilisateur tape par exemple "WAR/BRD/DRK/PLD" ou "WAR BRD DRK PLD" ou "WAR,BRD,DRK,PLD" j'espère que LIKE n'est pas embété avec le séparateur utilisé :s)
Ce que je souhaite c'est que si l'utilisateur change de Level ou de MainJob, les DataViews servant de Datasource aux comboboxs des equipements soient re-filtrées correctement.
Voici mon code :
Les comboboxs MainJob1/SubJob1 et MainWeapon1/SubWeapon1 sont mutuellement exclusives, c'est pour ca que l'on m'avait conseillé d'utiliser des dataviews d'une même table, filtrées indépendamment l'une de l'autre.
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 Public Class MainWindow Shared MaxMainLevel As Byte = 85 Private Sub MainWindow_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Me.FoodTableAdapter.Fill(Me.DataSet.Food) Me.WeaponTableAdapter.Fill(Me.DataSet.Weapon) Me.AmmoTableAdapter.Fill(Me.DataSet.Ammo) Me.RangedTableAdapter.Fill(Me.DataSet.Ranged) Me.HeadTableAdapter.Fill(Me.DataSet.Head) Me.NeckTableAdapter.Fill(Me.DataSet.Neck) Me.HandsTableAdapter.Fill(Me.DataSet.Hands) Me.BodyTableAdapter.Fill(Me.DataSet.Body) Me.RingTableAdapter.Fill(Me.DataSet.Ring) Me.EarTableAdapter.Fill(Me.DataSet.Ear) Me.WaistTableAdapter.Fill(Me.DataSet.Waist) Me.BackTableAdapter.Fill(Me.DataSet.Back) 'TODO*: cette ligne de code charge les données dans la table 'DataSet.Legs'. Vous pouvez la déplacer ou la supprimer selon vos besoins. Me.LegsTableAdapter.Fill(Me.DataSet.Legs) 'TODO*: cette ligne de code charge les données dans la table 'DataSet.Feet'. Vous pouvez la déplacer ou la supprimer selon vos besoins. Me.FeetTableAdapter.Fill(Me.DataSet.Feet) Me.Damage_TypesTableAdapter.Fill(Me.DataSet.Damage_Types) Me.Skills_ListTableAdapter.Fill(Me.DataSet.Skills_List) Me.Jobs_ListTableAdapter.Fill(Me.DataSet.Jobs_List) Dim MainJob1View As DataView = New DataView(Me.DataSet.Jobs_List) MainJob1View.Sort = "Jobs ASC" Me.MainJob1.DataSource = MainJob1View Me.MainJob1.DisplayMember = "Jobs" Dim SubJob1View As DataView = New DataView(Me.DataSet.Jobs_List) SubJob1View.RowFilter = "Jobs <>'" & Me.MainJob1.Text & "'" SubJob1View.Sort = "Jobs ASC" Me.SubJob1.DataSource = SubJob1View Me.SubJob1.DisplayMember = "Jobs" Me.SubJob2.DataSource = SubJob2View Me.SubJob2.DisplayMember = "Jobs" Me.SubJob1.Text = "No SubJob" Dim MainWeapon1View As DataView = New DataView(Me.DataSet.Weapon) MainWeapon1View.Sort = "Names ASC" Me.MainWeapon1.DataSource = MainWeapon1View Me.MainWeapon1.DisplayMember = "Names" Dim SubWeapon1View As DataView = New DataView(Me.DataSet.Weapon) SubWeapon1View.Sort = "Names ASC" Me.SubWeapon1.DataSource = SubWeapon1View Me.SubWeapon1.DisplayMember = "Names" Me.MainWeapon1.Text = Nothing Me.SubWeapon1.Text = Nothing Me.MainLevel1.Maximum = MaxMainLevel Me.MainLevel1.Value = Me.MainLevel1.Maximum Me.SubLevel1.Maximum = Math.Floor(Me.MainLevel1.Maximum / 2) Me.SubLevel1.Value = Math.Floor(Me.MainLevel1.Value / 2) End Sub Private Sub MainLevel1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MainLevel1.ValueChanged Me.SubLevel1.Maximum = Math.Floor(Me.MainLevel1.Value / 2) UpdateEquip1List() End Sub Private Sub MainJob1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MainJob1.TextChanged Dim SubJob1View As DataView = New DataView(Me.DataSet.Jobs_List) SubJob1View.RowFilter = "Jobs <>'" & Me.MainJob1.Text & "'" SubJob1View.RowStateFilter = DataViewRowState.CurrentRows Me.SubJob1.DataSource = SubJob1View Me.SubJob1.DisplayMember = "Jobs" Me.SubJob1.Text = "No SubJob" UpdateEquip1List() End Sub Private Sub MainWeapon1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MainWeapon1.TextChanged UpdateEquip1List() End Sub Private Sub SubWeapon1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles SubWeapon1.TextChanged UpdateEquip1List() End Sub Private Sub UpdateEquip1List() With Me.DataSet.Weapon.FindByNames(Me.MainWeapon1.Text) If .Equippable_Jobs.IndexOf(Me.MainWeapon1.Text) < 0 Or .Level > Me.MainLevel1.Value Then Me.MainWeapon1.Text = Nothing End If End With With Me.DataSet.Weapon.FindByNames(Me.SubWeapon1.Text) If .Equippable_Jobs.IndexOf(Me.SubWeapon1.Text) < 0 Or .Level > Me.MainLevel1.Value Then Me.SubWeapon1.Text = Nothing End If End With ' If MainWeapon1_TextChanged Or MainLevel1_ValueChanged Dim SubWeapon1View As DataView = New DataView(Me.DataSet.Weapon) ' SubWeapon1View.RowFilter = "NOT( Names = '" & Me.MainWeapon1.Text & "' AND 'Rare Tag' = 'True' ) AND 'Equippable Jobs' LIKE '*" & Me.MainJob1.Text & "*' AND Level <= '" & Me.MainLevel1.Value & "'" SubWeapon1View.RowFilter = "Names <> '" & Me.MainWeapon1.Text & "' AND 'Equippable Jobs' LIKE '*" & Me.MainJob1.Text & "*'" SubWeapon1View.RowStateFilter = DataViewRowState.CurrentRows Me.SubWeapon1.DataSource = SubWeapon1View Me.SubWeapon1.DisplayMember = "Names" ' If SubWeapon1_TextChanged Or MainLevel1_ValueChanged Dim MainWeapon1View As DataView = New DataView(Me.DataSet.Weapon) ' MainWeapon1View.RowFilter = "NOT( Names = '" & Me.SubWeapon1.Text & "' AND 'Rare Tag' = 'True' ) AND 'Equippable Jobs' LIKE '*" & Me.MainJob1.Text & "*' AND Level <= '" & Me.MainLevel1.Value & "'" MainWeapon1View.RowFilter = "Names <> '" & Me.SubWeapon1.Text & "' AND 'Equippable Jobs' LIKE '*" & Me.MainJob1.Text & "*'" MainWeapon1View.RowStateFilter = DataViewRowState.CurrentRows Me.MainWeapon1.DataSource = MainWeapon1View Me.MainWeapon1.DisplayMember = "Names" End Sub Public Sub UpdateEquip2List() End Sub ... End Class
Je réutilise le principe ici, mais de façon étendue à une trentaine de comboboxs, dont certaines (comme les Main/Sub weapons présentées ci-dessus) sont mutuellement exclusives.
L'exemple ci-dessus signifie qu'un personnage ne peut s'equiper dans chaque main de 2x la même arme, si cette arme est estampillée "Rare" dans la BDD; ET que l'utilisateur ne peut trouver dans les listes déroulantes des comboboxs Main/Subweapons que les armes dont le niveau est inférieur à celui de leur perso, ET dont le job du perso est parmi celles de l'arme dans le DataTable Weapon.
Le code présenté ne fonctionne pas:
1. InnerException au chargement à cause de la procédure UpdateEquipList()...
Je ne vois pas du tout qu'est ce que ma proc a de mal tourné... normalement cette proc n'est appelée QUE sur les événements de changements du contenu des comboboxs ... pourquoi planter au chargement ?
2. la string pour RowFilter semble ne pas fonctionner: celle commentée est la vraie, celle du dessous me servait de deboguage... le résultat est le même: comboboxs toujours vides
3. Chacune de mes datatables ont minimum 300lignes sur 40 colonnes, je ne sait pas si la conception que j'ai adopté est la bonne en termes de performance? Parce que si je lis mon code correctement, il va réactualiser les listes de mes 30 comboboxs à la moindre incrémentation de MainLevel1 ou MainJob1... ca fait mal Docteur ?
N'hésitez pas si ce n'est pas clair.
Merci d'avance pour vos réponses.
Partager