Bonjour

J'essaye de binder un objet sur un UserControl qui se trouve dans un ItemsControl via un convertisseur mais sa ne fonctionne pas correctement.
Le bind est configuré en mode TwoWay mais il fonctionne en mode OneWay, c'est à dire que la fonction ConvertBack du convertisseur n'est pas appelée.
Par conséquent, mes données convertie s'affichent bien mais si je les modifie alors elle ne se mettent pas à jour dans l'objet source.

Je ne vois pas ou est le problème, voici mon code en bas de page.

Mon objectif est de réaliser un UserControl nommé "Formulaire" qui reçois un objet quelconque en entrée et qui permet de lister et de modifier la valeur de ses propriétés.
Pour cela, j'ai utilisé un convertisseur qui permet de convertir l'objet reçu en List (Of Propriete) afin de pouvoir l'afficher dans l'itemscontrol.

La fonction Convert du convertisseur fonctionne car mes données sont bien affichée mais elle ne sont pas mise à jour quand je les modifie via la textbox.


Code xaml : 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
<UserControl x:Class="Formulaire"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Exemple_MVVM_Formulaire"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <local:Convert_ObjectVersProprietes x:Key="Convert_ObjectVersProprietes"/>
    </UserControl.Resources>
    <Grid>
 
        <DockPanel MaxHeight="700">
            <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
                <ItemsControl x:Name="Control" ItemsSource="{Binding Path=MonAdresse, Converter={StaticResource Convert_ObjectVersProprietes}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
 
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Grid Margin="0,0,0,5">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="100" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>
                                <TextBlock Text="{Binding Path=Nom}" />
                                <TextBox Text="{Binding Path=Valeur, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" />
                            </Grid>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
 
                </ItemsControl>
            </ScrollViewer>
        </DockPanel>
 
    </Grid>
</UserControl>

Convertisseur
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
 
 
Public Class Convert_ObjectVersProprietes
    Implements IValueConverter
 
    Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
 
        Dim Proprietes As New ObservableCollection(Of Propriete)
 
        Dim ProprietesInfos As PropertyInfo() = value.GetType().GetProperties()
        For Each ProprieteInfos In ProprietesInfos
            Proprietes.Add(New Propriete With {.Nom = ProprieteInfos.Name, .Valeur = ProprieteInfos.GetValue(value), .Type = ProprieteInfos.PropertyType.Name})
        Next
 
        Return Proprietes
    End Function
 
    Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
 
        Dim Proprietes As ObservableCollection(Of Propriete) = value
 
        Dim Objet As Object = Activator.CreateInstance(Type.GetType(targetType.Assembly.ToString & "." & targetType.ToString))
        Dim typeObjet As Type = Objet.GetType
 
 
        For Each Propriete As Propriete In Proprietes
            Dim p As PropertyInfo = typeObjet.GetProperty(Propriete.Nom)
            p.SetValue(Objet, Propriete.Valeur, Nothing)
        Next
 
        Return Objet
 
    End Function
 
End Class
Objet "Propriete"

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
 
         Public Class Propriete
    Inherits BindableBase
 
    Private _Nom As String
    Public Property Nom As String
        Get
            Return _Nom
        End Get
        Set(ByVal Valeur As String)
            SetProperty(_Nom, Valeur)
        End Set
    End Property
 
 
    Private _Valeur As Object
    Public Property Valeur As Object
        Get
            Return _Valeur
        End Get
        Set(ByVal Value As Object)
            SetProperty(_Valeur, Value)
        End Set
    End Property
 
 
    Private _Type As String
    Public Property Type As String
        Get
            Return _Type
        End Get
        Set(ByVal Valeur As String)
            SetProperty(_Type, Valeur)
        End Set
    End Property
 
End Class
Objet Adresse

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
 
 
Public Class Adresse
    Inherits BindableBase
 
    Private _Identifiant As String
    Public Property Identifiant As String
        Get
            Return _Identifiant
        End Get
        Set(ByVal Valeur As String)
            SetProperty(_Identifiant, Valeur)
        End Set
    End Property
 
 
    Private _Rue As String
    Public Property Rue As String
        Get
            Return _Rue
        End Get
        Set(ByVal Valeur As String)
            SetProperty(_Rue, Valeur)
        End Set
    End Property
 
 
    Private _Numero As Integer
    Public Property Numero As Integer
        Get
            Return _Numero
        End Get
        Set(ByVal Valeur As Integer)
            SetProperty(_Numero, Valeur)
        End Set
    End Property
 
 
    Private _Boite As Integer
    Public Property Boite As Integer
        Get
            Return _Boite
        End Get
        Set(ByVal Valeur As Integer)
            SetProperty(_Boite, Valeur)
        End Set
    End Property
 
 
    Private _CodePostal As Integer
    Public Property CodePostal As Integer
        Get
            Return _CodePostal
        End Get
        Set(ByVal Valeur As Integer)
            SetProperty(_CodePostal, Valeur)
        End Set
    End Property
 
 
    Private _Ville As String
    Public Property Ville As String
        Get
            Return _Ville
        End Get
        Set(ByVal Valeur As String)
            SetProperty(_Ville, Valeur)
        End Set
    End Property
 
 
    Private _Pays As String
    Public Property Pays As String
        Get
            Return _Pays
        End Get
        Set(ByVal Valeur As String)
            SetProperty(_Pays, Valeur)
        End Set
    End Property
 
 
    Private _Commentaire As String
    Public Property Commentaire As String
        Get
            Return _Commentaire
        End Get
        Set(ByVal Valeur As String)
            SetProperty(_Commentaire, Valeur)
        End Set
    End Property
 
End Class
ViewModel contenant l'adresse


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
 
 
Public Class MainViewModel
 
    Inherits BindableBase
 
    Private _MonAdresse As New Adresse
    Public Property MonAdresse As Adresse
        Get
            Return _MonAdresse
        End Get
        Set(ByVal Valeur As Adresse)
            SetProperty(_MonAdresse, Valeur)
        End Set
    End Property
  End Class
MainWindow

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
 
 
Class MainWindow
 
    Public MonFormulaire As New Formulaire
 
    Private _MainViewModel As New MainViewModel
    Sub New()
 
        ' Cet appel est requis par le concepteur.
        InitializeComponent()
 
        ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
        DataContext = _MainViewModel
 
        _MainViewModel.MonAdresse.Identifiant = 1
        _MainViewModel.MonAdresse.Rue = "Rue test"
        _MainViewModel.MonAdresse.Numero = 4
        _MainViewModel.MonAdresse.Boite = 5
        _MainViewModel.MonAdresse.CodePostal = 5000
        _MainViewModel.MonAdresse.Ville = "Test"
        _MainViewModel.MonAdresse.Pays = "Test"
        _MainViewModel.MonAdresse.Commentaire = "NA"
 
        GR1.Children.Add(MonFormulaire)
        MonFormulaire.DataContext = _MainViewModel
 
    End Sub
 
End Class
Je vous remercie pour votre aide