Bonjour,
Je viens du forum WinForms où j'avais déjà bien avancé un projet de conversion en VB.NET WinForms d'un comparateur développé sous Excel: un membre du forum m'avait conseillé de repartir à 0 en WPF pour faire la même chose en beaucoup + simple et + de possibilités (en particulier Comboboxs à 2 colonnes, ou encore infobulles imagées sur mousehover d'un item de combobox).
Donc j'ai suivi son conseil mais j'avoue j'ai du mal pour filtrer mes vues de datasets (créées auto par VB2010).
Pour l'instant voilà ce que j'ai dans le code XAML :
Code xml : 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
116
117
118 <Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Final Fantasy XI Melee Damage Comparator v6.0" Name="MainWindow" Height="768" Width="1024" MinHeight="600" MinWidth="800" WindowStartupLocation="CenterScreen" WindowStyle="ThreeDBorderWindow" Icon="/FFXIMDCwpf1;component/Images/PoroggoIcon.jpg" xmlns:my="clr-namespace:WpfApplication1"> <Window.Resources> <my:DataSet x:Key="DataSet" /> <CollectionViewSource x:Key="JobsListViewSource" Source="{Binding Path=JobsList, Source={StaticResource DataSet}}" /> <CollectionViewSource x:Key="WeaponViewSource" Source="{Binding Path=Weapon, Source={StaticResource DataSet}}" /> </Window.Resources> <Grid Name="Compare"> <Grid.ColumnDefinitions> <ColumnDefinition Width="350" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <StackPanel Name="CompareInputs" Grid.Column="0" > <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="50" /> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <TextBlock Name="Setup1" Grid.Column="1" Text="Setup 1" TextAlignment="Center" FontWeight="Bold" FontSize="14" /> <TextBlock Name="Setup2" Grid.Column="2" Text="Setup 2" TextAlignment="Center" FontWeight="Bold" FontSize="14" /> </Grid> <Expander Name="Expander1" Header="Race, Jobs and Levels" IsExpanded="True" Background="{x:Null}"> <Grid DataContext="{StaticResource JobsListViewSource}"> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="50"/> <ColumnDefinition /> <ColumnDefinition Width="25"/> </Grid.ColumnDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Margin="2">Race</TextBlock> <ComboBox Name="Race1" Grid.Column="1" Grid.ColumnSpan="2" VerticalContentAlignment="Center" Margin="2" Background="{x:Null}" BorderThickness="0" BorderBrush="{x:Null}" IsSynchronizedWithCurrentItem="False"> <ComboBoxItem Content="Elvaan"/> <ComboBoxItem Content="Galka"/> <ComboBoxItem Content="Hume"/> <ComboBoxItem Content="Mithra"/> <ComboBoxItem Content="Tarutaru"/> </ComboBox> <TextBlock Grid.Row="1" Grid.Column="0" Margin="2">MainJob</TextBlock> <ComboBox Name="MainJob" Grid.Row="1" Grid.Column="1" Margin="2,2,0,2" Background="{x:Null}" BorderBrush="{x:Null}" DisplayMemberPath="Names" SelectedValuePath="Jobs" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="False"/> <TextBox Name="MainLevel" Grid.Row="1" Grid.Column="2" MaxLength="2" BorderBrush="{x:Null}" Text="00" /> <TextBlock Grid.Row="2" Grid.Column="0" Margin="2">SubJob</TextBlock> <ComboBox Name="SubJob" Grid.Row="2" Grid.Column="1" Margin="2,2,0,2" Background="{x:Null}" BorderBrush="{x:Null}" DisplayMemberPath="Names" SelectedValuePath="Jobs" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="False"/> <TextBox Name="SubLevel" Grid.Row="2" Grid.Column="2" MaxLength="2" BorderBrush="{x:Null}" Text="00" /> </Grid> </Expander> <Expander Name="Expander2" Header="TP Sets" IsExpanded="True"> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="50"/> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Menu Grid.Row="0" Grid.Column="0" Margin="2" ToolTip="Edit Database or Search Filter"> <Menu.Background> <ImageBrush ImageSource="/FFXIMDCwpf1;component/Images/AxeIcon.jpg" Stretch="Uniform" /> </Menu.Background> <MenuItem Height="22" Width="44"> <MenuItem Header="Edit Database" /> <MenuItem Header="Search Filter"> <MenuItem Header="Axes" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Clubs" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Daggers" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Katanas" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Swords" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Great Axes" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Great Swords" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Great Katanas" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Polearms" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Scythes" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Staves" IsCheckable="True" StaysOpenOnClick="True"/> </MenuItem> </MenuItem> </Menu> <ComboBox Name="MainWeapon1" Grid.Row="0" Grid.Column="1" VerticalContentAlignment="Center" IsEditable="True" IsReadOnly="True" Margin="2" BorderBrush="{x:Null}" DisplayMemberPath="Names" ItemsSource="{Binding Source={StaticResource WeaponViewSource}}" IsSynchronizedWithCurrentItem="False" /> <ComboBox Name="MainWeapon2" Grid.Row="0" Grid.Column="2" VerticalContentAlignment="Center" IsEditable="True" IsReadOnly="True" Margin="2" BorderBrush="{x:Null}" DisplayMemberPath="Names" ItemsSource="{Binding Source={StaticResource WeaponViewSource}}" IsSynchronizedWithCurrentItem="False" /> <Menu Grid.Row="1" Grid.Column="0" Margin="2" ToolTip="Edit Database or Search Filter"> <Menu.Background> <ImageBrush ImageSource="/FFXIMDCwpf1;component/Images/SwordIcon.jpg" Stretch="Uniform" /> </Menu.Background> <MenuItem Height="22" Width="44"> <MenuItem Header="Edit Database" /> <MenuItem Header="Search Filter"> <MenuItem Header="Axes" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Clubs" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Daggers" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Katanas" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Swords" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Grips" IsCheckable="True" StaysOpenOnClick="True"/> <MenuItem Header="Shields" IsCheckable="True" StaysOpenOnClick="True"/> </MenuItem> </MenuItem> </Menu> <ComboBox Name="SubWeapon1" Grid.Row="1" Grid.Column="1" VerticalContentAlignment="Center" IsEditable="True" IsReadOnly="True" Margin="2" BorderBrush="{x:Null}" DisplayMemberPath="Names" ItemsSource="{Binding Source={StaticResource WeaponViewSource}}" IsSynchronizedWithCurrentItem="False"/> <ComboBox Name="SubWeapon2" Grid.Row="1" Grid.Column="2" VerticalContentAlignment="Center" IsEditable="True" IsReadOnly="True" Margin="2" BorderBrush="{x:Null}" DisplayMemberPath="Names" ItemsSource="{Binding Source={StaticResource WeaponViewSource}}" IsSynchronizedWithCurrentItem="False"/> <Menu Grid.Row="2" Grid.Column="0" Margin="2" ToolTip="Edit Database"> <Menu.Background> <ImageBrush ImageSource="/FFXIMDCwpf1;component/Images/BowIcon.jpg" Stretch="Uniform" /> </Menu.Background> <MenuItem Height="22" Width="44"/> </Menu> </Grid> </Expander> </StackPanel> <TabControl Name="CompareOutputs" Grid.Column="1" /> </Grid> </Window>
...et dans le code behind (.vb):
Code vb.net : 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 Class MainWindow Private Sub MainWindow_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded Dim DataSet As WpfApplication1.DataSet = CType(Me.FindResource("DataSet"), WpfApplication1.DataSet) 'Chargez les données dans la table JobsList. Vous pouvez modifier ce code si nécessaire. Dim DataSetJobsListTableAdapter As WpfApplication1.DataSetTableAdapters.JobsListTableAdapter = New WpfApplication1.DataSetTableAdapters.JobsListTableAdapter() DataSetJobsListTableAdapter.Fill(DataSet.JobsList) Dim JobsListViewSource As System.Windows.Data.CollectionViewSource = CType(Me.FindResource("JobsListViewSource"), System.Windows.Data.CollectionViewSource) JobsListViewSource.View.MoveCurrentToFirst() 'Chargez les données dans la table Weapon. Vous pouvez modifier ce code si nécessaire. Dim DataSetWeaponTableAdapter As WpfApplication1.DataSetTableAdapters.WeaponTableAdapter = New WpfApplication1.DataSetTableAdapters.WeaponTableAdapter() DataSetWeaponTableAdapter.Fill(DataSet.Weapon) Dim WeaponViewSource As System.Windows.Data.CollectionViewSource = CType(Me.FindResource("WeaponViewSource"), System.Windows.Data.CollectionViewSource) WeaponViewSource.View.MoveCurrentToFirst() End Sub End Class
Ces codes fonctionnent mais les comboboxs ne sont pas filtrées (et donc TRES longues pour certaines) rendant l'utilisation de l'UI vraiment fastidieuse...
Les datatables utilisées ont le format suivant :
- JobsList (Jobs, Names): Jobs est une colonne contenant les métiers en toutes lettres, Names est la 2e colonne avec les codes métiers correspondants (utilisée en SelectedValue).
- Weapon (Names, Equippable Jobs, Level, RareTag, ....)
Nota: j'ai également 15 autres datatables non mentionées ici mais même format que Weapon.
Les différents filtrages souhaités sont :
1) Cbx MainJob Source="JobsListViewSource.Jobs" Filter= <> SubJob.value
2) idem pour Cbx Subjob filtrée <> MainJob.value
3) Cbx MainWeapon1 Source="WeaponViewSource.Names" Filter=AND[isnumber(find(MainJob.SelectedValue, WeaponViewSource.EquippableJobs)), WeaponViewSource.Level<=MainLevel.value, si(WeaponviewSource.Names(SubWeapon1).RareTag="YES", "<>SubWeapon1")]
3bis) Idem pour la cbx MainWeapon2 mais avec SubWeapon2 (au lieu de 1)
4 et 4bis) idem que les filtrages 3 et 3bis mais appliquées pour les cbx Subweapon1 et 2 par rapport aux cbx MainWeapon1 & 2 resp.
En gros, je cherche à faire du filtrage exclusif bi-directionnel entre 2 comboboxs, en XAML (si possible avec 0 code behind).
D'après mes recherches je n'ai trouvé qu'une phrase sur MSDN (pas d'exemple):...mais sur 2 threads sur ce même forum, j'ai trouvé une syntaxe ressemblant à :Use CollectionViewSource object to benefit from sorting and filtering functionalities
mais c'est tout...
Code : Sélectionner tout - Visualiser dans une fenêtre à part <CollectionViewSource Filter="" ... />
L'autre question, d'ordre structural pour essayer d'écrire un code XAML "propre", est : Serait-il possible de mettre les <CollectionViewSource .../> dans le <RowDefinition /> contenant les comboboxs se servant de cette View ? (au lieu de mettre toutes les vues dans le Windows.Ressources). je n'ai pas réussi avec DataContext= , Binding=, Source= , etc...
Merci d'avance
Partager