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 :

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>
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
 
<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>
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
 
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};
        }
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.
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 !