Bonjour,
Je découvre WPF et j'ai besoin de dessiner environ 30 000 polylines ou polygones représentant des communes dans un canvas. Voici mes contraintes principales :
-Toutes peuvent être visibles en même temps, la carte est zoomable/dezoomable
-Je dois pouvoir sélectionner chaque polyline/polygone et accèder aux informations de l'entité (le nom, le code...) associée.
-Les formes doivent être remplissables (avec une couleur)
-le contrôle doit être réactif
J'ai déjà fais une première version avec un datatemplate qui représente mes entités par des polylines comme ceci :
Toujours côté XAML voici comment je m'y prend pour affecter mes entités à un canvas:
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 <DataTemplate x:Key="EntPolyLineTemplate"> <Polyline Points="{Binding Points}" Stroke="Black" StrokeThickness="1"> <Polyline.ToolTip> <StackPanel Orientation="Horizontal"> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Margin="4" Text="{Binding Id}" FontWeight="Bold"/> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Name}"/> </StackPanel> </Polyline.ToolTip> <Polyline.RenderTransform> <TransformGroup> <ScaleTransform ScaleY="-1"/> <TranslateTransform Y="3000"/> </TransformGroup> </Polyline.RenderTransform> <Polyline.Style> <Style TargetType="Polyline"> <Setter Property="Fill" Value="Azure"/> <Style.Triggers> <EventTrigger RoutedEvent="MouseEnter" > <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetProperty="Fill.Color" From="Blue" To="Azure" Duration="0:0:0.5"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Polyline.Fill" Value="Red"/> </Trigger> </Style.Triggers> </Style> </Polyline.Style> </Polyline>
Et enfin côté code-behind:
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 <WrapPanel Name="wrapPanel1" Background="Beige"> <ItemsControl ItemsSource="{Binding Entities}" ItemTemplateSelector="{StaticResource entityDataTemplateSelector}"> <ItemsControl.Resources> </ItemsControl.Resources> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas> <Canvas.LayoutTransform> <TransformGroup> <ScaleTransform ScaleX="{Binding ElementName=slider1, Path=Value}" ScaleY="{Binding ElementName=slider1, Path=Value}"/> </TransformGroup> </Canvas.LayoutTransform> </Canvas> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemContainerStyle> <Style TargetType="{x:Type ContentPresenter}"> <Setter Property="Canvas.Left" Value="{Binding X}"/> <Setter Property="Canvas.Top" Value="{Binding Y}"/> </Style> </ItemsControl.ItemContainerStyle> </ItemsControl> <Slider Minimum="0.1" Maximum="2" Height="21" Name="slider1" Width="100" /> </WrapPanel>
Bien cette version fonctionne parfaitement sauf pour ce qui est de la réactivité, il faut bien 1 ou 2s avant de pouvoir zoomer lorsque toute la carte est affichée... Il me faut donc trouver comment améliorer tout ça.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 public Window1() { InitializeComponent(); WPFVxf vxf = new WPFVxf(); System.Console.Out.WriteLine("Début du parsing:"+DateTime.Now.ToString()); vxf.load("c:\\fr_dep.vxf"); //vxf.load("c:\\fr_infracommunale.vxf"); System.Console.Out.WriteLine("Fin du parsing:" + DateTime.Now.ToString()); this.DataContext = new { Entities=vxf.Entities}; }
Mes pistes :
-Rendre asynchrone le dessin des polylines, l'idée serait que les polylines s'affichent au fur et à mesure (quitte à ce que cela se voie à l'écran); Problème: je n'ai pas trouvé où placer la propriété IsAsync...
-D'après MSDN utiliser des Drawing plutôt que des Shapes serait plus performant; Problème: il n'y a pas d'objet représentant un polygone, je pourrais dessiner des lines mais après comment faire pour remplir la forme crée ?? et quid du test de survol à la souris..?
Voilà j'aurais bien besoin de votre avis, merci !
Partager