Bonjour,

J'ai un "carrousel" constitué de ContentControls avec une animation des éléments dans le déplacement.

Lorsque l'on descend (Flèche 'Bas' sur le clavier), un nouveau ContentControl (caché hors de la grille dans un premier temps) est créé en bas et ensuite animé..et à l'inverse, au dessus, celui qui est alors masqué est supprimé!

Nom : forum.png
Affichages : 204
Taille : 2,3 Ko

Avec la flèche gauche/droite du clavier on remonte/descend d'une page complète!

En inspectant l'utilisation de la mémoire je me suis rendu compte que la mémoire n'est pas libérée lorsque je descend 1 par 1.
Les 'anciens' ContentControl sont bien effacés au fur et à mesure de la grille (et d'un dictionnaire qui contient les éléments disponibles)..mais la mémoire n'est pas libérée.

Elle l'est par contre quand on remonte/descend d'une page (il faut dire qu'il y a alors un reset des enfants de la grille et du dictionnaire)

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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
Imports System.IO
Imports System.Windows.Media.Animation
 
Class MainWindow
    Dim personDB As New List(Of Person)
    Dim listDictionary As Dictionary(Of Integer, ContentControl)
    Dim masterIndex As Integer = 0
    Dim delay As Double = 0.2
    ' ***** List settings *****
    Dim ListItemsNumber As Integer = 4      ' Number of items up and down the focused item
    Dim FocusedItemCoeff As Double = 2.5    ' Scale ration for focused item
    Dim ItemHeight As Integer               ' Height for a non-focused item
    Dim ItemCoordinates(ListItemsNumber * 2 + 3) As Integer
    '
    Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        SetCoordinates()
        SetPersons()
        CreateList(masterIndex)
    End Sub
    Sub SetCoordinates()
        ItemHeight = Math.Floor(ListGrid.ActualHeight / (ListItemsNumber * 2 + FocusedItemCoeff))
        ' Top hidden Item
        ItemCoordinates(0) = ItemHeight * -1
        ' Top Items
        For up As Integer = 1 To ListItemsNumber
            ItemCoordinates(up) = ItemHeight * (up - 1)
        Next
        ' Center Item
        ItemCoordinates(ListItemsNumber + 1) = ItemHeight * ListItemsNumber
        ' Bottom items
        For down As Integer = 1 To ListItemsNumber
            ItemCoordinates(ListItemsNumber + 1 + down) = Math.Floor(ItemHeight * ((down - 1) + FocusedItemCoeff + ListItemsNumber))
        Next
        ' Bottom hidden Item
        ItemCoordinates(ListItemsNumber * 2 + 2) = Math.Floor(ItemHeight * (ListItemsNumber * 2 + FocusedItemCoeff))
    End Sub
    Sub SetPersons()
        For i As Integer = 1 To 200
            personDB.Add(New Person() With {.lastName = "LastName" & i.ToString, .imageUrl = "01.jpg"})
        Next
    End Sub
    Sub CreateList(focusedIndex As Integer)
        ' Clear grid and dictionary
        ListGrid.Children.Clear()
        listDictionary = New Dictionary(Of Integer, ContentControl)
        ' Top Items
        For up As Integer = 1 To ListItemsNumber
            If (focusedIndex - up > -1) Then
                Dim cc As New ContentControl
                cc.ContentTemplate = DirectCast(Me.Resources("ccImage"), DataTemplate)
                cc.Height = ItemHeight
                cc.Width = 200
                cc.VerticalAlignment = Windows.VerticalAlignment.Top
                cc.Margin = New Thickness(0, ItemCoordinates(ListItemsNumber + 1 - up), 0, 0)
                cc.Content = New Displayed With {.lastName = personDB(focusedIndex - up).lastName, .imageUrl = personDB(focusedIndex - up).imageUrl}
                listDictionary.Add(focusedIndex - up, cc)
                ListGrid.Children.Add(cc) 
            End If
        Next
        ' Center Item
        If personDB.Count >= 0 Then
            Dim cc As New ContentControl
            cc.ContentTemplate = DirectCast(Me.Resources("ccImage"), DataTemplate)
            cc.Height = Math.Floor(ItemHeight * FocusedItemCoeff)
            cc.Width = 300
            cc.VerticalAlignment = Windows.VerticalAlignment.Top
            cc.Margin = New Thickness(0, ItemCoordinates(ListItemsNumber + 1), 0, 0)
            Dim dp As Displayed = New Displayed With {.lastName = personDB(focusedIndex).lastName, .imageUrl = personDB(focusedIndex).imageUrl}
            cc.Content = dp
            listDictionary.Add(focusedIndex, cc)
            ListGrid.Children.Add(cc)
        End If
        ' Bottom Items
        For down As Integer = 1 To ListItemsNumber
            If (focusedIndex + down <= personDB.Count - 1) Then
                Dim cc As New ContentControl
                cc.ContentTemplate = DirectCast(Me.Resources("ccImage"), DataTemplate)
                cc.Height = ItemHeight
                cc.Width = 200
                cc.VerticalAlignment = Windows.VerticalAlignment.Top
                cc.Margin = New Thickness(0, ItemCoordinates(ListItemsNumber + 1 + down), 0, 0)
                Dim dp As Displayed = New Displayed With {.lastName = personDB(focusedIndex + down).lastName, .imageUrl = personDB(focusedIndex + down).imageUrl}
                cc.Content = dp
                listDictionary.Add(focusedIndex + down, cc)
                ListGrid.Children.Add(cc)
            End If
        Next
    End Sub
    Private Sub MainWindow_KeyDown(ByVal sender As Object, ByVal keyData As System.Windows.Input.KeyEventArgs) Handles Me.KeyDown
        If keyData.Key = Key.Down Then
            If masterIndex < personDB.Count - 1 Then
                GoDown()
            End If
        ElseIf keyData.Key = Key.Left Then
            If masterIndex > 0 Then
                If (masterIndex >= ListItemsNumber * 2 + 1) Then
                    masterIndex -= ListItemsNumber * 2 + 1
                Else
                    masterIndex = 0
                End If
                CreateList(masterIndex)
            End If
        ElseIf keyData.Key = Key.Right Then
            If masterIndex < personDB.Count - 1 Then
                If (masterIndex + (ListItemsNumber * 2 + 1) <= personDB.Count - 1) Then
                    masterIndex += ListItemsNumber * 2 + 1
                Else
                    masterIndex = personDB.Count - 1
                End If
                CreateList(masterIndex)
            End If
        End If
    End Sub
    Sub GoDown()
        ' Remove Top Hidden Item
        If listDictionary.ContainsKey(masterIndex - ListItemsNumber - 1) Then
            ListGrid.Children.Remove(listDictionary(masterIndex - ListItemsNumber - 1))
            listDictionary.Remove(masterIndex - ListItemsNumber - 1)
        End If
        ' Add new item at bottom
        If masterIndex + ListItemsNumber + 1 <= personDB.Count - 1 Then
            Dim cc As New ContentControl
            cc.ContentTemplate = DirectCast(Me.Resources("ccImage"), DataTemplate)
            cc.Height = ItemHeight
            cc.Width = 200
            cc.VerticalAlignment = Windows.VerticalAlignment.Top
            cc.Margin = New Thickness(0, ItemCoordinates(ListItemsNumber * 2 + 2), 0, 0)
            Dim dp As Displayed = New Displayed With {.lastName = personDB(masterIndex + ListItemsNumber + 1).lastName, .imageUrl = personDB(masterIndex + ListItemsNumber + 1).imageUrl}
            cc.Content = dp
            listDictionary.Add(masterIndex + ListItemsNumber + 1, cc)
            ListGrid.Children.Add(cc)
        End If
        '
        Dim myStoryboard As New Storyboard()
        '
        ' Top animation
        For up As Integer = 1 To ListItemsNumber
            If (masterIndex - up > -1) Then
                'Animating Margins
                Dim myDoubleAnimation As New ThicknessAnimation()
                Dim marginThickness As Thickness = listDictionary(masterIndex - up).Margin
                Dim NewmarginThickness As Thickness = New Thickness(0, ItemCoordinates(ListItemsNumber - up), 0, 0)
                myDoubleAnimation.From = marginThickness
                myDoubleAnimation.To = NewmarginThickness
                myDoubleAnimation.Duration = New Duration(TimeSpan.FromSeconds(delay))
                'myDoubleAnimation.EasingFunction = ease
                Storyboard.SetTarget(myDoubleAnimation, listDictionary(masterIndex - up))
                Storyboard.SetTargetProperty(myDoubleAnimation, New PropertyPath(Grid.MarginProperty))
                myStoryboard.Children.Add(myDoubleAnimation)
            End If
        Next
 
        ' Center animation
        If personDB.Count >= 0 Then
            If (masterIndex < personDB.Count - 1) Then
                'Animating Margins
                Dim myDoubleAnimation As New ThicknessAnimation()
                Dim marginThickness As Thickness = listDictionary(masterIndex).Margin
                Dim NewmarginThickness As Thickness = New Thickness(0, ItemCoordinates(ListItemsNumber), 0, 0)
                myDoubleAnimation.From = marginThickness
                myDoubleAnimation.To = NewmarginThickness
                myDoubleAnimation.Duration = New Duration(TimeSpan.FromSeconds(delay))
                Storyboard.SetTarget(myDoubleAnimation, listDictionary(masterIndex))
                Storyboard.SetTargetProperty(myDoubleAnimation, New PropertyPath(Grid.MarginProperty))
                myStoryboard.Children.Add(myDoubleAnimation)
                'Animating Height
                Dim myDoubleAnimation2 As New DoubleAnimation()
                Dim prevHeight As Integer = listDictionary(masterIndex).Height
                Dim newHeight As Integer = ItemHeight
                myDoubleAnimation2.From = prevHeight
                myDoubleAnimation2.To = newHeight
                myDoubleAnimation2.Duration = New Duration(TimeSpan.FromSeconds(delay))
                Storyboard.SetTarget(myDoubleAnimation2, listDictionary(masterIndex))
                Storyboard.SetTargetProperty(myDoubleAnimation2, New PropertyPath(Grid.HeightProperty))
                myStoryboard.Children.Add(myDoubleAnimation2)
                'Animating Width
                Dim myDoubleAnimation3 As New DoubleAnimation()
                Dim prevWidth As Integer = listDictionary(masterIndex).Width
                Dim newWidth As Integer = 200
                myDoubleAnimation3.From = prevWidth
                myDoubleAnimation3.To = newWidth
                myDoubleAnimation3.Duration = New Duration(TimeSpan.FromSeconds(delay))
                Storyboard.SetTarget(myDoubleAnimation3, listDictionary(masterIndex))
                Storyboard.SetTargetProperty(myDoubleAnimation3, New PropertyPath(Grid.WidthProperty))
                myStoryboard.Children.Add(myDoubleAnimation3)
            End If
        End If
        ' Bottom animation
        If (masterIndex + 1 <= personDB.Count - 1) Then
            'Animating Height
            Dim myDoubleAnimation2 As New DoubleAnimation()
            Dim prevHeight As Integer = listDictionary(masterIndex + 1).Height
            Dim newHeight As Integer = Math.Floor(ItemHeight * FocusedItemCoeff)
            myDoubleAnimation2.From = prevHeight
            myDoubleAnimation2.To = newHeight
            myDoubleAnimation2.Duration = New Duration(TimeSpan.FromSeconds(delay))
            Storyboard.SetTarget(myDoubleAnimation2, listDictionary(masterIndex + 1))
            Storyboard.SetTargetProperty(myDoubleAnimation2, New PropertyPath(Grid.HeightProperty))
            myStoryboard.Children.Add(myDoubleAnimation2)
            'Animating Width
            Dim myDoubleAnimation3 As New DoubleAnimation()
            Dim prevWidth As Integer = listDictionary(masterIndex + 1).Width
            Dim newWidth As Integer = 300
            myDoubleAnimation3.From = prevWidth
            myDoubleAnimation3.To = newWidth
            myDoubleAnimation3.Duration = New Duration(TimeSpan.FromSeconds(delay))
            Storyboard.SetTarget(myDoubleAnimation3, listDictionary(masterIndex + 1))
            Storyboard.SetTargetProperty(myDoubleAnimation3, New PropertyPath(Grid.WidthProperty))
            myStoryboard.Children.Add(myDoubleAnimation3)
        End If
        For down As Integer = 1 To ListItemsNumber + 1
            If (masterIndex + down <= personDB.Count - 1) Then
                'Animating Margins
                Dim myDoubleAnimation As New ThicknessAnimation()
                Dim marginThickness As Thickness = listDictionary(masterIndex + down).Margin
                Dim NewmarginThickness As Thickness = New Thickness(0, ItemCoordinates(ListItemsNumber + down), 0, 0)
                myDoubleAnimation.From = marginThickness
                myDoubleAnimation.To = NewmarginThickness
                myDoubleAnimation.Duration = New Duration(TimeSpan.FromSeconds(delay))
                Storyboard.SetTarget(myDoubleAnimation, listDictionary(masterIndex + down))
                Storyboard.SetTargetProperty(myDoubleAnimation, New PropertyPath(Grid.MarginProperty))
                myStoryboard.Children.Add(myDoubleAnimation)
            End If
        Next
        myStoryboard.Begin()
        '
        masterIndex += 1
    End Sub
End Class
 
Public Class Person
    Public Shared ReadOnly DescriptComparer As New DescriptComparerClass
    Public lastName As String
    Public imageUrl As String
    Sub New()
    End Sub
    Public Class DescriptComparerClass
        Implements IComparer(Of Person)
        Public Function Compare(ByVal x As Person, ByVal y As Person) As Integer Implements System.Collections.Generic.IComparer(Of Person).Compare
            Return String.Compare(x.lastName, y.lastName, True)
        End Function
    End Class
End Class
 
Public Class Displayed
    Public _lastname As String
    Public _imageUrl As String
    Public Property lastName() As String
        Get
            Return _lastname
        End Get
        Set(value As String)
            _lastname = value
        End Set
    End Property
    Public Property imageUrl() As String
        Get
            Return _imageUrl
        End Get
        Set(value As String)
            _imageUrl = value
        End Set
    End Property
    Sub New()
    End Sub
End Class
 
Public Class ImagePathConverter
    Implements IValueConverter
    Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.Convert
        Dim relative As [String] = TryCast(value, String)
        If String.IsNullOrEmpty(relative) Then
            Return Nothing
        End If
        Return System.AppDomain.CurrentDomain.BaseDirectory & "Images\" & relative
    End Function
    Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
        Throw New NotImplementedException()
    End Function
End Class
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
<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"    
    Title="MainWindow" Height="700" Width="800">
    <Window.Resources>
        <local:ImagePathConverter x:Key="imgPathConverter" />
        <DataTemplate x:Key="ccImage" >
            <Border Padding="4">
                <Image>
                    <Image.Source>
                        <BitmapImage UriSource="{Binding imageUrl, Converter={StaticResource imgPathConverter}}" CacheOption="OnLoad" CreateOptions="IgnoreImageCache" RenderOptions.BitmapScalingMode="LowQuality"/>
                    </Image.Source>
                </Image>
            </Border>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <Grid Name="ListGrid" Width="400" VerticalAlignment="Top" Height="600" HorizontalAlignment="Left" Background="Black"></Grid>
    </Grid>
</Window>
Le problème intervient donc dans cette partie

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
Sub GoDown()
        ' Remove Top Hidden Item
        If listDictionary.ContainsKey(masterIndex - ListItemsNumber - 1) Then
            ListGrid.Children.Remove(listDictionary(masterIndex - ListItemsNumber - 1))
            listDictionary.Remove(masterIndex - ListItemsNumber - 1)
        End If
...le ContentControl enlevé de la grille semble toujours être existant "quelque part" ;-) car la mémoire grossit de plus en plus lors du défilement vers le bas (sur l'exemple joint, j'arrive à 500Mo sur une liste de 200 objets)

J'espère que je suis assez clair dans mes explications et que vous voudrez bien m'aider! Merci
NB: pour que le code marche, il faut créer un dossier 'Images' avec un fichier '01.jpg' à l'intérieur, au niveau de l'application.
On se déplace avec les flèches 'bas, gauche, droite'