'How to get selected value on SelectionChanged event of ComboBox in ViewModel (WPF-MVVM)?

I am new in WPF Application with pattern MVVM and I have a particular situation that I do not know how to solve it.

I builted a system to switch environments (Productive, WorkDebug and HomeDebug) with changing only a parameter. I created this system, because every environment have different type Classes and without it, every time that I need to switch environment I have to perform commenct/uncomment on properties and so on.

I have a Class with a switch that handles the execution and determine what type of variable initialize:

Private _modalitaEsecuzione As Byte
'DATABASE
Private _ambienteDatabase As AmbienteDatabase
Private _databaseProduttivo As DatabaseProduttivoLinqToSqlDataContext
Private _databaseDebug As DatabaseLinqToSqlDataContext
Private _databaseDebugHome As DatabaseLinqToSqlHomeDataContext

Private _ambienteSettori As AmbienteSettore


Private _ambienteUtente As AmbienteUtente

Private _ambienteProprietaSettore As AmbienteProprietaSettore

Public Sub New(produttivoDebug As Byte)

    _modalitaEsecuzione = produttivoDebug

End Sub
Public Function ImpostaVariabile(tipoFunzione As String)

    Select Case tipoFunzione
        Case "percorsoFilesFilRouge"
            If _modalitaEsecuzione = AmbienteEsecuzioneEnum.Produttivo Then
                Return "productivePath"

            ElseIf _modalitaEsecuzione = AmbienteEsecuzioneEnum.DebugLavoro Then
                Return "workDebugPath"

            Else
                Return "homeDebugPath"

            End If
        Case "databaseConnection"
            If _modalitaEsecuzione = AmbienteEsecuzioneEnum.Produttivo Then

                _ambienteDatabase = New AmbienteDatabase() With {
                    .DatabaseProduttivo = New DatabaseProduttivoLinqToSqlDataContext(ConfigurationManager.
                    ConnectionStrings("productiveConnection").ToString())
                }
                Return _ambienteDatabase

            ElseIf _modalitaEsecuzione = AmbienteEsecuzioneEnum.DebugLavoro Then

                _ambienteDatabase = New AmbienteDatabase() With {
                        .DatabaseDebugLavoro = New DatabaseLinqToSqlDataContext(MySettings.Default.DebugConnection)
                }
                Return _ambienteDatabase
            Else
                _ambienteDatabase = New AmbienteDatabase() With {
                    .DatabaseDebugHome = New DatabaseLinqToSqlHomeDataContext(ConfigurationManager.
                    ConnectionStrings("HomeDebugConnection").ToString())
                }

                Return _ambienteDatabase
            End If
        Case "listaSettori"
            If _modalitaEsecuzione = AmbienteEsecuzioneEnum.Produttivo Then
                _ambienteSettori = New AmbienteSettore() With {
                    .SettoriProduttivo = New ObservableCollection(Of T_Settore)(_ambienteDatabase.DatabaseProduttivo.
                    T_Settore.Where(Function(s) s.NSET_Disponibilita > 0).
                    OrderBy(Function(s) s.TSET_Descrizione).ToList())
                }
                Return _ambienteSettori

            ElseIf _modalitaEsecuzione = AmbienteEsecuzioneEnum.DebugLavoro Then
                _ambienteSettori = New AmbienteSettore() With {
                    .SettoriDebugLavoro = New ObservableCollection(Of T_Settore_Debug)(_ambienteDatabase.
                    DatabaseDebugLavoro.
                    T_Settore_Debug.Where(Function(s) s.NSET_Disponibilita > 0).
                    OrderBy(Function(s) s.TSET_Descrizione).ToList())
                }

                Return _ambienteSettori
            Else
                _ambienteSettori = New AmbienteSettore() With {
                    .SettoriDebugHome = New ObservableCollection(Of T_Settore_Debug_Home)(_ambienteDatabase.
                    DatabaseDebugHome.
                    T_Settore_Debug_Homes.Where(Function(s) s.NSET_Disponibilita > 0).
                    OrderBy(Function(s) s.TSET_Descrizione).ToList())
                }

                Return _ambienteSettori
            End If
        Case "listaUtenti"
            If _modalitaEsecuzione = AmbienteEsecuzioneEnum.Produttivo Then
                _ambienteUtente = New AmbienteUtente() With {
                    .UtentiDatabaseProduttivo = _ambienteDatabase.DatabaseProduttivo.T_Ospite.ToList()
                }

                Return _ambienteUtente

            ElseIf _modalitaEsecuzione = AmbienteEsecuzioneEnum.DebugLavoro Then

                _ambienteUtente = New AmbienteUtente() With {
                    .UtentiDatabaseDebug = _ambienteDatabase.DatabaseDebugLavoro.Utente_Debug.ToList()
                }

                Return _ambienteUtente
            Else
                _ambienteUtente = New AmbienteUtente() With {
                    .UtentiDatabaseDebugHome = _ambienteDatabase.DatabaseDebugHome.Utente_Debug_Homes.ToList()
                }
                Return _ambienteUtente
            End If
        Case "proprietaSettore"
            If _modalitaEsecuzione = AmbienteEsecuzioneEnum.Produttivo Then
                Dim proprietaSettoreProduttivo = _ambienteDatabase.DatabaseProduttivo.T_Settore.
                    Where(Function(s) s.TSET_Codice Is "SND").
                    SingleOrDefault()
                _ambienteProprietaSettore = New AmbienteProprietaSettore() With {
                    .SettoreProduttivo = proprietaSettoreProduttivo,
                    .CodiceSettore = proprietaSettoreProduttivo.TSET_Codice
                }

                Return _ambienteProprietaSettore

            ElseIf _modalitaEsecuzione = AmbienteEsecuzioneEnum.DebugLavoro Then
                Dim proprietaSettoreDebug = _ambienteDatabase.DatabaseDebugLavoro.T_Settore_Debug.
                    Where(Function(s) s.TSET_Codice Is "INF").
                    SingleOrDefault()
                _ambienteProprietaSettore = New AmbienteProprietaSettore() With {
                    .SettoreDebug = proprietaSettoreDebug,
                    .CodiceSettore = proprietaSettoreDebug.TSET_Codice
                }

                Return _ambienteProprietaSettore
            Else
                Dim proprietaSettoreDebugHome = _ambienteDatabase.DatabaseDebugHome.T_Settore_Debug_Homes.
                    Where(Function(s) s.TSET_Codice Is "INF").
                    SingleOrDefault()

                _ambienteProprietaSettore = New AmbienteProprietaSettore() With {
                    .SettoreDebug = proprietaSettoreDebugHome,
                    .CodiceSettore = proprietaSettoreDebugHome.TSET_Codice
                }

                Return _ambienteProprietaSettore
            End If
        Case "utente"


    End Select
    Return ""
End Function
End Class

In my ViewModel I instantiate this class and I set various properties with that object. Now, I have a list of object that is bound to the View and the type of this list depends on the environments that is selected. In this class I have three different type classes properties who corresponds to a specific environment:

Public Class AmbienteSettore
    Private _settoriProduttivo As ObservableCollection(Of T_Settore)
    Public Property SettoriProduttivo() As ObservableCollection(Of T_Settore)
        Get
            Return _settoriProduttivo
        End Get
        Set(ByVal value As ObservableCollection(Of T_Settore))
            _settoriProduttivo = value
        End Set
    End Property

    Private _settoriDebugLavoro As ObservableCollection(Of T_Settore_Debug)
    Public Property SettoriDebugLavoro() As ObservableCollection(Of T_Settore_Debug)
        Get
            Return _settoriDebugLavoro
        End Get
        Set(ByVal value As ObservableCollection(Of T_Settore_Debug))
            _settoriDebugLavoro = value
        End Set
    End Property

    Private _settoriDebugHome As ObservableCollection(Of T_Settore_Debug_Home)
    Public Property SettoriDebugHome() As ObservableCollection(Of T_Settore_Debug_Home)
        Get
            Return _settoriDebugHome
        End Get
        Set(ByVal value As ObservableCollection(Of T_Settore_Debug_Home))
            _settoriDebugHome = value
        End Set
    End Property

    Public Function GetSettori()
        Return SettoriProduttivo
    End Function
End Class

In my ViewModel I declare a property of this class to determine what kind of list. This properties is bound with the combobox and I use a Converter to determine the list type and then to pass it to the XAML that it will be able to manage the list properly. The Converter convert the object to their right list (Productive, WorkDebug and HomeDebug):

    Public Class ListaSettoriConverter
        Implements IValueConverter

        Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
            value = DirectCast(value, AmbienteSettore)
            If value.SettoriProduttivo IsNot Nothing Then
                Return value.SettoriProduttivo
            ElseIf value.SettoriDebugLavoro IsNot Nothing Then
                Return value.SettoriDebugLavoro
            Else
                Return value.SettoriDebugHome
            End If
        End Function

        Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
            Throw New NotImplementedException()
        End Function

    End Class

To intercept the SelectionChanged I need to link a single object of the list with a single property in my ViewModel. This property has the same logic of the list: I have different type classes based on environment. The class of the single property is

Public Class AmbienteProprietaSettore

Private _settoreProduttivo As T_Settore
Public Property SettoreProduttivo() As T_Settore
    Get
        Return _settoreProduttivo
    End Get
    Set(ByVal value As T_Settore)
        _settoreProduttivo = value

    End Set
End Property

Private _settoreDebug As T_Settore_Debug
Public Property SettoreDebug() As T_Settore_Debug
    Get
        Return _settoreDebug
    End Get
    Set(ByVal value As T_Settore_Debug)
        _settoreDebug = value
    End Set
End Property
Private _settoreDebugHome As T_Settore_Debug_Home
Public Property SettoreDebugHome() As T_Settore_Debug_Home
    Get
        Return _settoreDebugHome
    End Get
    Set(ByVal value As T_Settore_Debug_Home)
        _settoreDebugHome = value


    End Set
End Property
End Class

This is the XAML ComboBox:

<ComboBox HorizontalAlignment="Left" VerticalAlignment="Center" Width="200" Margin="5 0 0 0" 
                  ItemsSource="{Binding Path=AmbienteSettore, Converter={StaticResource ListaSettoriConverter}}" 
                  SelectedItem="{Binding Path=AmbienteProprietaSettore, UpdateSourceTrigger=PropertyChanged, 
                    Converter={StaticResource SettoreConverter}}"

The question is, how can I manage the NotifyPropertyChanged of a property that is inside a property of the ViewModel? Because the binding is based on the class which has the right properties set inside it.

I hope that is clear and thanks in advance



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source