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
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 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 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 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
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
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
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 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
Je vous remercie pour votre aide
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
Partager