Search code examples
vb.netxamlbinding

Binding multiples Class in Wpf


I can't link 2 TextBoxes to properties defined in 2 classes. I tested this simple example Where is the error, please?

My XAML:

<Window x:Class="MainWindow"

        xmlns:local="clr-namespace:WpfApp_multiBinding" xmlns:multipleviewmodel="clr-namespace:WpfApp_multiBinding.MultipleViewModel" d:DataContext="{d:DesignInstance Type=local:MainWindow}"
        mc:Ignorable="d"
        Title="MainWindow">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" x:Name="SP1" Orientation="Horizontal" >
            <TextBlock  Text="{Binding ViewModels.ViewMod1.Text1}"/>
        </StackPanel>
        <StackPanel Grid.Row="1" x:Name="SP2" Orientation="Horizontal">
            <TextBlock Text="{Binding ViewModels.ViewMod2.Text2}"/>
        </StackPanel>
    </Grid>
</Window>

The MainWindow:

    Imports WpfApp_multiBinding.MultipleViewModel
    
    Class MainWindow
            Public ViewModels As ViewModels
    
            Sub New()
                InitializeComponent()
    
                ViewModels = New ViewModels
                DataContext = ViewModels
    
                SP1.DataContext = ViewModels.ViewMod1
                SP2.DataContext = ViewModels.ViewMod2
    
                ViewModels.ViewMod1.Text1 = "toto"
                ViewModels.ViewMod2.Text2 = "titi"
            End Sub
        End Class

My classes

    Imports System.ComponentModel
    
    Namespace MultipleViewModel
    
        Public Class ViewModels
            Public ViewMod1 As New ViewModel1
            Public ViewMod2 As New ViewModel2
        End Class
    
        Public Class ViewModel1
    
            Implements INotifyPropertyChanged
            Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
    
            Public Sub OnPropertyChanged(ByVal e As PropertyChangedEventArgs)
                If PropertyChangedEvent IsNot Nothing Then
                    RaiseEvent PropertyChanged(Me, e)
                End If
            End Sub
    
            Private Property _Text1 As String
    
            Public Property Text1 As String
                Get
                    Return _Text1
                End Get
                Set(value As String)
                    _Text1 = value
                    OnPropertyChanged(New PropertyChangedEventArgs(NameOf(Text1)))
                End Set
            End Property
    
        End Class
    Public Class ViewModel2
... idem Class VieModel1 ...
End Class
    End Namespace

Solution

  • In your MainWindow's constructor, you are providing a new DataContext to your StackPanels (SP1 and SP2):

    SP1.DataContext = ViewModels.ViewMod1
    SP2.DataContext = ViewModels.ViewMod2
    

    Every control in each StackPanel inherits the DataContext of the StackPanel, not the MainWindow's DataContext. Your TextBlock bindings should therefore be adjusted accordingly:

    <StackPanel Grid.Row="0" x:Name="SP1" Orientation="Horizontal" >
        <TextBlock Text="{Binding Text1}"/>
    </StackPanel>
    <StackPanel Grid.Row="1" x:Name="SP2" Orientation="Horizontal">
        <TextBlock Text="{Binding Text2}"/>
    </StackPanel>
    

    The bindings you currently have are the equivalent to ViewModels.ViewMod1.ViewModels.ViewMod1.Text1 and ViewModels.ViewMod2.ViewModels.ViewMod2.Text2.