IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Sauvegarder un UIElementCollection dans un fichier


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 106
    Par défaut Sauvegarder un UIElementCollection dans un fichier
    Bonjour,

    Je développe actuellement un application utilisant un InkCanvas
    Je permet à l'utilisateur d'y ajouter des textbox et des images et je les places dans mon InkCanvas1.Children 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
            Dim NewTextBox = New TextBox
            NewTextBox.Text = "TextBlock content"
            NewTextBox.Background = Nothing
            NewTextBox.BorderBrush = Nothing
            NewTextBox.TextWrapping = TextWrapping.Wrap
            NewTextBox.AcceptsReturn = True
            Canvas.SetTop(NewTextBox, 100)
            Canvas.SetLeft(NewTextBox, 100)
            InkCanvas1.Children.Add(NewTextBox)
     
            Dim NewImage = New Image
            NewImage.Source = New BitmapImage(New Uri("C:\Users\Famille\Desktop\Document Reader\WpfApplication1\Images\xps_icon.png"))
            Canvas.SetTop(NewImage, 500)
            Canvas.SetLeft(NewImage, 500)
            InkCanvas1.Children.Add(NewImage)
    Comment peut-on sauvegarder le InkCanvas1.Children dans un fichier?
    (en sachant qu'il n'y a pas de méthode .Save)

    Éric

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 106
    Par défaut
    Bon,

    J'ai trouvé comment sauvegarder:
    Il faut sérialiser chaque objets de la collection pour les écrire dans un fichier Xaml.

    Par contre, ma collection contient des TextBox et des Images qui ne sont pas sérialiser.
    J'ai essayé de créer une classe dérivé qui Implémenterais TextBox (et image) et qui serrais Sérialisé mais, encore là, ça ne fonctionne pas
    car la classe de base ne l'est pas.

    Existe-t-il une méthode pour contourner cela?

    Merci.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Tu fais comment pour sérialiser ? Normalement avec XamlWriter ça devrait marcher...

  4. #4
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut enregistrer un children de InkCanvas
    bonjour Eric_M
    Excuse-moi de reprendre tout.
    C'est un mauvais tour du clavier ou de mes doigts.................
    Comme dit par Tomlev ,seule la serialisation xaml peut venir à bout de ton probleme.
    1/la possibilite de sauvegarder un instanane de tout le contenu de ton InkCanvas dans un fichier fichier bitmap Strokes et UIElement dans un meme fichier,en utilisant la classe RenderTargetBitmap ..

    2/ la possibilite de sauvegarder un UIElement dans un fichier au format Xaml avec la classe XamlWriter et recharger bien ce fichier avec XamlReader.....
    (on peut bien sur sauvegarder le InkCanvas lui-meme en entier.......) mais :
    -sauf helas les images ,car en Xaml XamlWriter ne sauvegardera pas l'image mais son chemin et encore un chemin s.v.p en absolu et non en relatif ce qui rend le fichier non transportable.....Tu peux jeter un coup d'oeil
    par curiosite au fichier Xaml dans l'exemple de code ci-apres.

    Par consequent dans cette 3eme methode s'il y a des childrens images ,il faut parcourir InkCanvas pour les reperer et les sauver un à un avec la 2eme methode ( RenderTargetBitmap).......
    voici un exemple de code avec :
    -une liste ObservableCollection(of FrameWorkElement) qui permet de visualiser ta liste d'element ajoutes à InkCanvas...dans un combo et un listview
    La liste est necessaire car la collection Children n'est pas helas bindable car c'est une collection ReadOnly.....
    -1 bouton sauvegarde en image bitmap de tout le canvas.
    -1 bouton sauvgarde d'un FrameworkElement choisi dans Combo...
    -1 bouton charger un FrameworkElement sauve precedemment.....
    - et 2 boutons pour ajouter des frameworkelements par code....
    code behind du winform:
    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
     
    'pour FileStream
    Imports System.IO
    ' pour  XamlWriter
    Imports System.Windows.Markup
    ' pour  ObservableCollection
    Imports System.Collections.ObjectModel
     
    Partial Public Class Window3
    	Private lstChilds As ObservableCollection(Of FrameworkElement) = New ObservableCollection(Of FrameworkElement)
    	Private ndxElemToSave As Integer = -1
    	Public Sub New()
    		' Cet appel est requis par le Concepteur Windows Form.
    		InitializeComponent()
    		' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
    		For Each child As FrameworkElement In Me.myInkCanvas.Children
    			If child.GetType IsNot GetType(Image) Then
    				lstChilds.Add(child)
    			End If
    		Next
    		Me.myLVChildren.ItemsSource = lstChilds
    		Me.myCBOChildren.ItemsSource = lstChilds
    	End Sub
    	'dessine un textbox et un bouton
    	Private Sub DrawText_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    		Dim NewTextBox = New TextBox
    		NewTextBox.Name = "myTextBlock"
    		NewTextBox.Text = "TextBlock content"
    		NewTextBox.Background = Brushes.Linen
    		NewTextBox.BorderBrush = Nothing
    		NewTextBox.TextWrapping = TextWrapping.Wrap
    		NewTextBox.AcceptsReturn = True
    		InkCanvas.SetTop(NewTextBox, 100)
    		InkCanvas.SetLeft(NewTextBox, 100)
    		Me.myInkCanvas.Children.Add(NewTextBox)
    		lstChilds.Add(NewTextBox)
     
    		'plus un gros bouton
    		Dim NewButton = New Button
    		NewButton.Name = "MyButton"
    		NewButton.Content = "MyButton"
    		NewButton.Background = Brushes.Chartreuse
    		NewButton.BorderBrush = Nothing
    		NewButton.HorizontalContentAlignment = Windows.HorizontalAlignment.Center
    		NewButton.Opacity = 0.6
    		NewButton.Height = 80
    		NewButton.Width = 100
    		InkCanvas.SetTop(NewButton, 150)
    		InkCanvas.SetLeft(NewButton, 100)
    		Me.myInkCanvas.Children.Add(NewButton)
    		lstChilds.Add(NewButton)
    	End Sub
    	'charge une image pour etre dessiner
    	Private Sub DrawImage_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    		'ajoute une  image dans  InkCanvas
    		Dim NewImage = New Image
    		Dim pathImage As String = String.Empty
    		pathImage = GetPathImage()
    		If Len(pathImage) <> 0 Then
    			NewImage.Name = "MyNewImage"
    			NewImage.Source = New BitmapImage(New Uri(pathImage))
    			NewImage.Width = Me.myInkCanvas.ActualWidth
    			NewImage.Height = Me.myInkCanvas.ActualHeight
    			InkCanvas.SetTop(NewImage, 100)
    			InkCanvas.SetLeft(NewImage, 150)
    			Me.myInkCanvas.Children.Add(NewImage)
    			lstChilds.Add(NewImage)
    		End If
    	End Sub
    	'Sub specialise pour  chargement des images 
    	Private Function GetPathImage() As String
    		'Specify the filePath for  image 
    		Dim fileNameImage As String = String.Empty
    		'Configure open file dialog box
    		Dim dlg As New Microsoft.Win32.OpenFileDialog()
    		dlg.FileName = "Images"	' Default file name
    		dlg.DefaultExt = ".png"	' Default file extension
    		dlg.Filter = "Fichiers Images(*.png,*.jpg)|*.png;*.jpg"	' Filter files by extension
     
    		' Show open file dialog box
    		Dim result As Boolean = dlg.ShowDialog()
     
    		' Process open file dialog box results
    		If result = True Then
    			' Open image
    			fileNameImage = dlg.FileName
     
    		End If
    		If Len(fileNameImage) <> 0 Then
    			Return fileNameImage
    		Else
    			MessageBox.Show("specifier un nom de fichier image .s.v.p..")
    		End If
    		Return Nothing
    	End Function
     
    	'sauve tout InkCanvas comme une image bitmap =>  methode  2
    	Private Sub SaveAllAsImage_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
     
    		'Specify the filePath for saving your drawing 
    		Dim fileName As String = String.Empty
    		'Configure save file dialog box
    		Dim dlg As New Microsoft.Win32.SaveFileDialog()
    		dlg.FileName = "DrawingImage" ' Default file name
    		dlg.DefaultExt = ".png"	' Default file extension
    		dlg.Filter = "DrawingImage(.png)|*.png"	' Filter files by extension
     
    		' Show save file dialog box
    		Dim result As Boolean = dlg.ShowDialog()
     
    		' Process open file dialog box results
    		If result = True Then
    			' Save document
    			fileName = dlg.FileName
     
    		End If
    		If Len(fileName) <> 0 Then
    			Dim myUri As Uri = New Uri(fileName)
    			ExportToPng(myUri, Me.myInkCanvas)
    		Else
    			MessageBox.Show("specifier un nom de fichier.s.v.p..")
    		End If
    	End Sub
    	Public Sub ExportToPng(ByVal pathUri As Uri, ByVal objInkCanvas As InkCanvas)
     
    		If pathUri.OriginalString = String.Empty Then Return
    		'Save current canvas transform
    		Dim transform As Transform = objInkCanvas.LayoutTransform
    		'reset current transform (in case it is scaled or rotated)
    		objInkCanvas.LayoutTransform = Nothing
     
    		'Get the size of canvas
    		Dim size As Size = New Size(objInkCanvas.ActualWidth, objInkCanvas.ActualHeight)
    		'Measure and arrange the surface
    		'VERY IMPORTANT
    		objInkCanvas.Measure(size)
    		objInkCanvas.Arrange(New Rect(size))
    		'Create a render bitmap and push the surface to it
    		Dim renderBitmap As RenderTargetBitmap = _
    		 New RenderTargetBitmap( _
    		   CType(size.Width, Integer), _
    		   CType(size.Height, Integer), _
    		   96D, _
    		   96D, _
    		   PixelFormats.Pbgra32)
    		renderBitmap.Render(objInkCanvas)
    		'Create a file stream for saving image
    		Using outStream As FileStream = New FileStream(pathUri.LocalPath, FileMode.Create)
    			'Use png encoder for our data
    			Dim encoder As PngBitmapEncoder = New PngBitmapEncoder()
    			'push the rendered bitmap to it
    			encoder.Frames.Add(BitmapFrame.Create(renderBitmap))
    			'save the data to the stream
    			encoder.Save(outStream)
    		End Using
    		'Restore previously saved layout
    		objInkCanvas.LayoutTransform = transform
    	End Sub
    	'sauve les childrens sauf image dans un fichier xaml=>  methode  3
    	Private Sub saveChildrens_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    		'La selection vide retour
    		If ndxElemToSave = -1 Then Return
     
    		'Specify the filePath for saving your drawing 
    		Dim fileName As String = String.Empty
    		'Configure save file dialog box
    		Dim dlg As New Microsoft.Win32.SaveFileDialog()
    		dlg.FileName = "MyDrawing" ' Default file name
    		dlg.DefaultExt = ".xaml"	' Default file extension
    		dlg.Filter = "Drawing documents (.xaml)|*.xaml"	' Filter files by extension
     
    		' Show save file dialog box
    		Dim result As Boolean = dlg.ShowDialog()
     
    		' Process open file dialog box results
    		If result = True Then
    			' Save document
    			fileName = dlg.FileName
     
    		End If
    		If Len(fileName) <> 0 Then
    			Dim cnvTemp As Canvas = New Canvas
    			Dim childToSave = Me.myInkCanvas.Children.Item(ndxElemToSave)
    			For Each child As FrameworkElement In Me.myInkCanvas.Children
    				If child.GetType IsNot GetType(Image) Then
    					ExportXaml(New Uri(fileName), child)
    				End If
    			Next
    		Else
    			MessageBox.Show("specifier un nom de fichier.s.v.p..")
    		End If
     
    	End Sub
    	'Exporting Child  to the XAML 
    	'I’ll give you the most stupid sample that can be found everywhere 
    	Public Sub ExportXaml(ByVal pathUri As Uri, ByVal childToSave As UIElement)
     
    		If pathUri.OriginalString = String.Empty Then Return
    		If childToSave Is Nothing Then Return
    		'Save  Child UIElement comme un string en memoire.
    		Dim stringUI As String = XamlWriter.Save(childToSave)
    		'Save  Child dans un File Xaml.
    		File.WriteAllText(pathUri.LocalPath, stringUI)
    	End Sub
    	'Exporting canvas to the XAML 
    	'I’ll give you the most stupid sample that can be found everywhere 
    	Public Sub ExportXamlPänel(ByVal pathUri As Uri, ByVal tempCanvas As Canvas)
     
    		If pathUri.OriginalString = String.Empty Then Return
    		If tempCanvas Is Nothing Then Return
    		'Save   UIElement comme un string en memoire.
    		Dim stringUI As String = XamlWriter.Save(tempCanvas)
    		'Save  tempCanvas dans un File Xaml.
    		File.WriteAllText(pathUri.LocalPath, stringUI)
    	End Sub
    	'charge un children  depuis un fichier xaml =>  methode  3
    	' ou plusieurs si on a sauve plusieurs........
    	Private Sub loadChildrens_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
     
    		'Specify the filePath for opening your drawing 
    		Dim fileName As String = String.Empty
    		'Configure open file dialog box
    		Dim dlg As New Microsoft.Win32.OpenFileDialog()
    		dlg.FileName = "MyDrawing" ' Default file name
    		dlg.DefaultExt = ".xaml"	' Default file extension
    		dlg.Filter = "Drawing documents (.xaml)|*.xaml"	' Filter files by extension
     
    		' Show open file dialog box
    		Dim result As Boolean = dlg.ShowDialog()
     
    		' Process open file dialog box results
    		If result = True Then
    			' Open document
    			fileName = dlg.FileName
    		End If
    		If Len(fileName) <> 0 Then
    			Me.myInkCanvas.Children.Clear()
    			Dim child As UIElement
    			child = ImportXaml(fileName)
    			Me.myInkCanvas.Children.Add(child)
    			Me.lstChilds.Add(child)
    		Else
    			MessageBox.Show("specifier un nom de fichier.s.v.p..")
    		End If
     
    	End Sub
    	Public Function ImportXaml(ByVal pathFile As String) As UIElement
     
    		If pathFile = String.Empty Then Return Nothing
     
    		' Ouvre le file comme un string.
    		Dim myReader As StreamReader = New StreamReader(pathFile, True)
    		'lit le fichier comme un stringReader
    		Dim stringUIElement As StringReader = New StringReader(myReader.ReadToEnd)
     
    		Dim xmlReader As Xml.XmlReader = Xml.XmlReader.Create(stringUIElement)
    		'charge le file comme UIElement
    		Dim readerInkCanvas As UIElement = CType(Markup.XamlReader.Load(xmlReader), UIElement)
    		myReader.Close()
    		Return readerInkCanvas
    	End Function
    	Private Sub LVChildren_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
    		'tu peux reprendre integralement le code dans le combo ci-dessous
    	End Sub
     
    	Private Sub ComboChildren_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
    		ndxElemToSave = -1
    		If (myCBOChildren.SelectedItem IsNot Nothing) Then
    			Dim elem As FrameworkElement = CType(myCBOChildren.SelectedItem, FrameworkElement)
    			If Me.myInkCanvas.Children.Contains(elem) Then
     
    				ndxElemToSave = Me.myInkCanvas.Children.IndexOf(elem)
    				MessageBox.Show("msg :" & ndxElemToSave.ToString)
    			End If
    		End If
     
    	End Sub
    End Class
    code xaml du winform:
    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
     
    <Window x:Class="Window3"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window3" Height="300" Width="300">
        <Window.Resources>
        </Window.Resources>
        <Grid
            HorizontalAlignment="Stretch"
            VerticalAlignment="Stretch">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" ></RowDefinition>
                <RowDefinition Height="32"  MaxHeight="32"></RowDefinition>
                <RowDefinition Height="32"  MaxHeight="32"></RowDefinition>
                <RowDefinition Height="64" MaxHeight="100"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" ></ColumnDefinition>
                <ColumnDefinition Width="*" ></ColumnDefinition>
                <ColumnDefinition Width="*" ></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <ScrollViewer 
                Grid.ColumnSpan ="3"
                VerticalScrollBarVisibility="Auto"
                HorizontalScrollBarVisibility="Auto">
               <Border 
                    BorderBrush="Blue" 
                    BorderThickness="4">  
                    <StackPanel 
                        Name="myStackPanel"> 
                       <InkCanvas 
                           Background="Yellow" 
                           Name="myInkCanvas"
                           MinWidth="500"
                           MinHeight="500">  
                            <Ellipse 
                                Name="myEllipse"
                                Fill="Red" 
                                Stroke="Black" 
                                StrokeThickness="2"
                                Width="100"
                                Height="80"
                                InkCanvas.Top="50"
                                InkCanvas.Left="50"></Ellipse>
                        </InkCanvas>
                    </StackPanel >
                </Border>
            </ScrollViewer>
            <!--dessine un textbox-->
            <Button 
                Grid.Row="1"
                Grid.Column="0"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                Name="DrawText"
                Click="DrawText_Click" FontSize="12">DrawText</Button>
            <!--charge une image pour etre dessiner-->
            <Button 
                Grid.Row="1"
                Grid.Column="1"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                Name="DrawImage"
                Click="DrawImage_Click" FontSize="12">DrawImage</Button>
           <!--sauve tout InkCanvas comme une image bitmap =>  methode  2-->
            <Button 
                Grid.Row="2"
                Grid.Column="0"
                Name="SaveAllAsImage"
                Background="BlanchedAlmond"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                Click="SaveAllAsImage_Click" 
                FontSize="12">SaveAllAsImage</Button>
            <!--sauve  un children sauf image dans un fichier xaml=>  methode  3-->
            <Button 
                Grid.Row="2"
                Grid.Column="1"
                Name="saveChildrens"
                Background="Aquamarine"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                Click="saveChildrens_Click" 
                FontSize="12">saveChildrens</Button>
           <!--charge un children  depuis un fichier xaml =>  methode  2--> 
           <!--charge plusieurs si on a sauve plusieurs........-->
            <Button 
                Grid.Row="2"
                Grid.Column="2"
                Name="loadChildrens"
                Background="Aqua"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                Click="loadChildrens_Click" 
                FontSize="12">loadChildrens</Button>
            <ListView 
                Grid.Row="3"
                Grid.ColumnSpan="2"
                Name="myLVChildren"
                SelectionMode="Single"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                IsSynchronizedWithCurrentItem="True"
                FontSize="12"
                SelectionChanged="LVChildren_SelectionChanged"
                ItemsSource="{Binding}">
                <ListView.View>
                    <GridView >
                        <GridViewColumn 
                            Header="Name"
                            DisplayMemberBinding="{Binding  Path=Name}">
                        </GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>
            <!--selectionne un children  pour sauvegarde dans un fichier xaml =>  methode  2-->
            <ComboBox  
                Grid.Row="3"
                Grid.Column="3"
                Name="myCBOChildren"
                Foreground="DarkSalmon"
                IsEditable="True"
                IsReadOnly="True"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                IsSynchronizedWithCurrentItem="True"
                FontSize="12"
                DisplayMemberPath="Name"
                SelectionChanged="ComboChildren_SelectionChanged"
                ItemsSource="{Binding}">
            </ComboBox>
        </Grid>
    </Window>
    Nota-bena: comme signale dans MSDN doc les elements serialises par xamlwriter sont de faux-semblants FrameworkElement quand on les recharges...
    Ils perdent leurs proprietes de binding,evenements.dans le jargon MSDN ils sont ou "freezable" ou geles je traduirais plutot par "figes" en bon francais ....
    Les elements de resources statiques comme les images sont perdus......c'est pour cela que j'ai inclus l'exemple "sauver" tout comme image bitmap.....
    bon code.................

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 106
    Par défaut
    Merci beaucoup à vous deux!

    MABROUKI, ton exemple complet m'a beaucoup aider à visualiser le fonctionnement du XamlWriter!

    Par contre, il y a une erreur qui a pour conséquence de sauvegarder seulement le dernier control dans le fichier Xaml.

    J'ai donc modifier un peu le code pour que chaque control sois sauvegarder dans le fichier (1 par ligne).
    (J'ai aussi ajouté des TextBox pour choisir la position des nouvelles TextBox (1 pour X, 1 pour Y)).

    Code VB:
    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
    281
    282
    283
    284
    285
    286
    287
    288
    289
     
    'pour FileStream
    Imports System.IO
    ' pour  XamlWriter
    Imports System.Windows.Markup
    ' pour  ObservableCollection
    Imports System.Collections.ObjectModel
     
    Partial Public Class Window3
        Private lstChilds As ObservableCollection(Of FrameworkElement) = New ObservableCollection(Of FrameworkElement)
        Private ndxElemToSave As Integer = -1
        Public Sub New()
            ' Cet appel est requis par le Concepteur Windows Form.
            InitializeComponent()
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            For Each child As FrameworkElement In Me.myInkCanvas.Children
                If child.GetType IsNot GetType(Image) Then
                    lstChilds.Add(child)
                End If
            Next
            Me.myLVChildren.ItemsSource = lstChilds
            Me.myCBOChildren.ItemsSource = lstChilds
        End Sub
        'dessine un textbox et un bouton
        Dim TextBoxNumber As Integer = 1
        Private Sub DrawText_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            TextBoxNumber += 1
     
            Dim NewTextBox = New TextBox
            NewTextBox.Name = "myTextBlock" & TextBoxNumber
            NewTextBox.Text = "TextBlock content"
            NewTextBox.Background = Brushes.Linen
            NewTextBox.BorderBrush = Nothing
            NewTextBox.TextWrapping = TextWrapping.Wrap
            NewTextBox.AcceptsReturn = True
            InkCanvas.SetTop(NewTextBox, Int(TextBox1.Text))
            InkCanvas.SetLeft(NewTextBox, Int(TextBox2.Text))
            Me.myInkCanvas.Children.Add(NewTextBox)
            lstChilds.Add(NewTextBox)
     
            'plus un gros bouton
            Dim NewButton = New Button
            NewButton.Name = "MyButton" & TextBoxNumber
            NewButton.Content = "MyButton"
            NewButton.Background = Brushes.Chartreuse
            NewButton.BorderBrush = Nothing
            NewButton.HorizontalContentAlignment = Windows.HorizontalAlignment.Center
            NewButton.Opacity = 0.6
            NewButton.Height = 80
            NewButton.Width = 100
            InkCanvas.SetTop(NewButton, 150)
            InkCanvas.SetLeft(NewButton, 100)
            Me.myInkCanvas.Children.Add(NewButton)
            lstChilds.Add(NewButton)
        End Sub
        'charge une image pour etre dessiner
        Private Sub DrawImage_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            'ajoute une  image dans  InkCanvas
            Dim NewImage = New Image
            Dim pathImage As String = String.Empty
            pathImage = GetPathImage()
            If Len(pathImage) <> 0 Then
                NewImage.Name = "MyNewImage"
                NewImage.Source = New BitmapImage(New Uri(pathImage))
                NewImage.Width = Me.myInkCanvas.ActualWidth
                NewImage.Height = Me.myInkCanvas.ActualHeight
                InkCanvas.SetTop(NewImage, 100)
                InkCanvas.SetLeft(NewImage, 150)
                Me.myInkCanvas.Children.Add(NewImage)
                lstChilds.Add(NewImage)
            End If
        End Sub
        'Sub specialise pour  chargement des images 
        Private Function GetPathImage() As String
            'Specify the filePath for  image 
            Dim fileNameImage As String = String.Empty
            'Configure open file dialog box
            Dim dlg As New Microsoft.Win32.OpenFileDialog()
            dlg.FileName = "Images" ' Default file name
            dlg.DefaultExt = ".png" ' Default file extension
            dlg.Filter = "Fichiers Images(*.png,*.jpg)|*.png;*.jpg" ' Filter files by extension
     
            ' Show open file dialog box
            Dim result As Boolean = dlg.ShowDialog()
     
            ' Process open file dialog box results
            If result = True Then
                ' Open image
                fileNameImage = dlg.FileName
     
            End If
            If Len(fileNameImage) <> 0 Then
                Return fileNameImage
            Else
                MessageBox.Show("specifier un nom de fichier image .s.v.p..")
            End If
            Return Nothing
        End Function
     
        'sauve tout InkCanvas comme une image bitmap =>  methode  2
        Private Sub SaveAllAsImage_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
     
            'Specify the filePath for saving your drawing 
            Dim fileName As String = String.Empty
            'Configure save file dialog box
            Dim dlg As New Microsoft.Win32.SaveFileDialog()
            dlg.FileName = "DrawingImage" ' Default file name
            dlg.DefaultExt = ".png" ' Default file extension
            dlg.Filter = "DrawingImage(.png)|*.png" ' Filter files by extension
     
            ' Show save file dialog box
            Dim result As Boolean = dlg.ShowDialog()
     
            ' Process open file dialog box results
            If result = True Then
                ' Save document
                fileName = dlg.FileName
     
            End If
            If Len(fileName) <> 0 Then
                Dim myUri As Uri = New Uri(fileName)
                ExportToPng(myUri, Me.myInkCanvas)
            Else
                MessageBox.Show("specifier un nom de fichier.s.v.p..")
            End If
        End Sub
        Public Sub ExportToPng(ByVal pathUri As Uri, ByVal objInkCanvas As InkCanvas)
     
            If pathUri.OriginalString = String.Empty Then Return
            'Save current canvas transform
            Dim transform As Transform = objInkCanvas.LayoutTransform
            'reset current transform (in case it is scaled or rotated)
            objInkCanvas.LayoutTransform = Nothing
     
            'Get the size of canvas
            Dim size As Size = New Size(objInkCanvas.ActualWidth, objInkCanvas.ActualHeight)
            'Measure and arrange the surface
            'VERY IMPORTANT
            objInkCanvas.Measure(size)
            objInkCanvas.Arrange(New Rect(size))
            'Create a render bitmap and push the surface to it
            Dim renderBitmap As RenderTargetBitmap = _
             New RenderTargetBitmap( _
               CType(size.Width, Integer), _
               CType(size.Height, Integer), _
               96D, _
               96D, _
               PixelFormats.Pbgra32)
            renderBitmap.Render(objInkCanvas)
            'Create a file stream for saving image
            Using outStream As FileStream = New FileStream(pathUri.LocalPath, FileMode.Create)
                'Use png encoder for our data
                Dim encoder As PngBitmapEncoder = New PngBitmapEncoder()
                'push the rendered bitmap to it
                encoder.Frames.Add(BitmapFrame.Create(renderBitmap))
                'save the data to the stream
                encoder.Save(outStream)
            End Using
            'Restore previously saved layout
            objInkCanvas.LayoutTransform = transform
        End Sub
        'sauve les childrens sauf image dans un fichier xaml=>  methode  3
        Private Sub saveChildrens_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            'La selection vide retour
            If ndxElemToSave = -1 Then Return
     
            'Specify the filePath for saving your drawing 
            Dim fileName As String = String.Empty
            'Configure save file dialog box
            Dim dlg As New Microsoft.Win32.SaveFileDialog()
            dlg.FileName = "MyDrawing" ' Default file name
            dlg.DefaultExt = ".xaml"    ' Default file extension
            dlg.Filter = "Drawing documents (.xaml)|*.xaml" ' Filter files by extension
     
            ' Show save file dialog box
            Dim result As Boolean = dlg.ShowDialog()
     
            ' Process open file dialog box results
            If result = True Then
                ' Save document
                fileName = dlg.FileName
     
            End If
            If Len(fileName) <> 0 Then
                'Dim cnvTemp As Canvas = New Canvas
                'Dim childToSave = Me.myInkCanvas.Children.Item(ndxElemToSave)
                Dim FileUri As New Uri(fileName)
                Dim AllControlsInXaml As New Text.StringBuilder
     
                For Each child As FrameworkElement In Me.myInkCanvas.Children
                    If child.GetType IsNot GetType(Image) Then
                        AllControlsInXaml.AppendLine(ExportXaml(FileUri, child))
                    End If
                Next
     
                'Save All Child dans un File Xaml.
                File.WriteAllText(FileUri.LocalPath, AllControlsInXaml.ToString)
            Else
                MessageBox.Show("specifier un nom de fichier.s.v.p..")
            End If
     
        End Sub
        'Exporting Child  to the XAML 
        'I’ll give you the most stupid sample that can be found everywhere 
        Public Function ExportXaml(ByVal pathUri As Uri, ByVal childToSave As UIElement) As String
     
            If pathUri.OriginalString = String.Empty Then Return Nothing
            If childToSave Is Nothing Then Return Nothing
            'Save  Child UIElement comme un string en memoire.
            Dim stringUI As String = XamlWriter.Save(childToSave)
            Return stringUI
            'Save  Child dans un File Xaml.
            'File.WriteAllText(pathUri.LocalPath, stringUI)
        End Function
     
        'charge un children  depuis un fichier xaml =>  methode  3
        ' ou plusieurs si on a sauve plusieurs........
        Private Sub loadChildrens_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
     
            'Specify the filePath for opening your drawing 
            Dim fileName As String = String.Empty
            'Configure open file dialog box
            Dim dlg As New Microsoft.Win32.OpenFileDialog()
            dlg.FileName = "MyDrawing" ' Default file name
            dlg.DefaultExt = ".xaml"    ' Default file extension
            dlg.Filter = "Drawing documents (.xaml)|*.xaml" ' Filter files by extension
     
            ' Show open file dialog box
            Dim result As Boolean = dlg.ShowDialog()
     
            ' Process open file dialog box results
            If result = True Then
                ' Open document
                fileName = dlg.FileName
            End If
            If Len(fileName) <> 0 Then
                Me.myInkCanvas.Children.Clear()
     
                Dim objReader As New System.IO.StreamReader(dlg.FileName)
                Dim XamlToString As String = objReader.ReadToEnd()
                objReader.Close()
     
                For Each line As String In XamlToString.Split(vbCrLf)
                    'charge le fichier comme UIElement
                    Dim xmlReader As Xml.XmlReader = Xml.XmlReader.Create(New StringReader(line))
                    Dim readerInkCanvas As UIElement = CType(Markup.XamlReader.Load(xmlReader), UIElement)
     
                    xmlReader.Close()
                    Me.myInkCanvas.Children.Add(readerInkCanvas)
                Next
     
            Else
                MessageBox.Show("specifier un nom de fichier.s.v.p..")
            End If
     
        End Sub
        Public Function ImportXaml(ByVal pathFile As String) As UIElement
     
            If pathFile = String.Empty Then Return Nothing
     
            ' Ouvre le file comme un string.
            Dim myReader As StreamReader = New StreamReader(pathFile, True)
            'lit le fichier comme un stringReader
     
            Dim stringUIElement As StringReader = New StringReader(myReader.ReadToEnd)
     
            Dim xmlReader As Xml.XmlReader = Xml.XmlReader.Create(stringUIElement)
            'charge le file comme UIElement
            Dim readerInkCanvas As UIElement = CType(Markup.XamlReader.Load(xmlReader), UIElement)
            myReader.Close()
            Return readerInkCanvas
        End Function
        Private Sub LVChildren_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
            'tu peux reprendre integralement le code dans le combo ci-dessous
        End Sub
     
        Private Sub ComboChildren_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
            ndxElemToSave = -1
            If (myCBOChildren.SelectedItem IsNot Nothing) Then
                Dim elem As FrameworkElement = CType(myCBOChildren.SelectedItem, FrameworkElement)
                If Me.myInkCanvas.Children.Contains(elem) Then
     
                    ndxElemToSave = Me.myInkCanvas.Children.IndexOf(elem)
                    MessageBox.Show("msg :" & ndxElemToSave.ToString)
                End If
            End If
     
        End Sub
    End Class
    Code Xaml:
    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
    <Window x:Class="Window3"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window3" Height="743" Width="776">
        <Window.Resources>
        </Window.Resources>
        <Grid
            HorizontalAlignment="Stretch"
            VerticalAlignment="Stretch">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" ></RowDefinition>
                <RowDefinition Height="32"  MaxHeight="32"></RowDefinition>
                <RowDefinition Height="32"  MaxHeight="32"></RowDefinition>
                <RowDefinition Height="64" MaxHeight="100"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" ></ColumnDefinition>
                <ColumnDefinition Width="*" ></ColumnDefinition>
                <ColumnDefinition Width="*" ></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <ScrollViewer 
                Grid.ColumnSpan ="3"
                VerticalScrollBarVisibility="Auto"
                HorizontalScrollBarVisibility="Auto">
                <Border 
                    BorderBrush="Blue" 
                    BorderThickness="4">
                    <StackPanel 
                        Name="myStackPanel">
                        <InkCanvas 
                           Background="Yellow" 
                           Name="myInkCanvas"
                           MinWidth="500"
                           MinHeight="500">
                            <Ellipse 
                                Name="myEllipse"
                                Fill="Red" 
                                Stroke="Black" 
                                StrokeThickness="2"
                                Width="100"
                                Height="80"
                                InkCanvas.Top="50"
                                InkCanvas.Left="50"></Ellipse>
                        </InkCanvas>
                    </StackPanel >
                </Border>
            </ScrollViewer>
            <!--dessine un textbox-->
            <Button 
                Grid.Row="1"
                Grid.Column="0"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                Name="DrawText"
                Click="DrawText_Click" FontSize="12">DrawText</Button>
            <!--charge une image pour etre dessiner-->
            <Button 
                Grid.Row="1"
                Grid.Column="1"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                Name="DrawImage"
                Click="DrawImage_Click" FontSize="12">DrawImage</Button>
            <!--sauve tout InkCanvas comme une image bitmap =>  methode  2-->
            <Button 
                Grid.Row="2"
                Grid.Column="0"
                Name="SaveAllAsImage"
                Background="BlanchedAlmond"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                Click="SaveAllAsImage_Click" 
                FontSize="12">SaveAllAsImage</Button>
            <!--sauve  un children sauf image dans un fichier xaml=>  methode  3-->
            <Button 
                Grid.Row="2"
                Grid.Column="1"
                Name="saveChildrens"
                Background="Aquamarine"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                Click="saveChildrens_Click" 
                FontSize="12">saveChildrens</Button>
            <!--charge un children  depuis un fichier xaml =>  methode  2-->
            <!--charge plusieurs si on a sauve plusieurs........-->
            <Button 
                Grid.Row="2"
                Grid.Column="2"
                Name="loadChildrens"
                Background="Aqua"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                Click="loadChildrens_Click" 
                FontSize="12">loadChildrens</Button>
            <ListView 
                Grid.Row="3"
                Grid.ColumnSpan="2"
                Name="myLVChildren"
                SelectionMode="Single"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                IsSynchronizedWithCurrentItem="True"
                FontSize="12"
                SelectionChanged="LVChildren_SelectionChanged"
                ItemsSource="{Binding}">
                <ListView.View>
                    <GridView >
                        <GridViewColumn 
                            Header="Name"
                            DisplayMemberBinding="{Binding  Path=Name}">
                        </GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>
            <!--selectionne un children  pour sauvegarde dans un fichier xaml =>  methode  2-->
            <ComboBox  
                Grid.Row="3"
                Grid.Column="3"
                Name="myCBOChildren"
                Foreground="DarkSalmon"
                IsEditable="True"
                IsReadOnly="True"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Center"
                IsSynchronizedWithCurrentItem="True"
                FontSize="12"
                DisplayMemberPath="Name"
                SelectionChanged="ComboChildren_SelectionChanged"
                ItemsSource="{Binding}">
            </ComboBox>
            <TextBox Grid.Column="2" Grid.Row="1" Height="23" Name="TextBox1" VerticalAlignment="Top" Margin="28,5,0,0" HorizontalAlignment="Left" Width="98" />
            <Label Content="X:" Grid.Column="2" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="2,2,0,0" Name="Label1" VerticalAlignment="Top" />
            <TextBox Height="23" HorizontalAlignment="Left" Margin="150,5,0,0" Name="TextBox2" VerticalAlignment="Top" Width="98" Grid.Column="2" Grid.Row="1" />
            <Label Content="Y:" Height="28" HorizontalAlignment="Left" Margin="126,2,0,0" Name="Label2" VerticalAlignment="Top" Grid.Column="2" Grid.Row="1" />
        </Grid>
    </Window>

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Sauvegarder les données dans un fichier CSV
    Par beb30 dans le forum MFC
    Réponses: 5
    Dernier message: 08/03/2006, 13h06
  2. Réponses: 5
    Dernier message: 21/10/2005, 11h48
  3. [C#] Sauvegarde de texture dans un fichier + transparence
    Par Harry_polin dans le forum DirectX
    Réponses: 13
    Dernier message: 23/07/2005, 18h12
  4. [arbre] Sauvegarder un objet dans un fichier
    Par Guigui_ dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2003, 00h55
  5. Sauvegarder une surface dans un fichier
    Par Freakazoid dans le forum DirectX
    Réponses: 6
    Dernier message: 18/08/2002, 15h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo