Results 1 to 4 of 4

Thread: Bind Textbox to Combobox in WPF (MVVM)

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Apr 2013
    Posts
    28

    Bind Textbox to Combobox in WPF (MVVM)

    Hey,

    I am working with WPF and the MVVM pattern for a few days now and it's kinda difficult compared to window forms. I tried to bind the selectedvalue from a combobox to a textbox. Sounds simple but I think I am lost
    This is my code:

    MainWindow.xaml
    Code:
    <Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="150" Width="150">
        <Window.Resources>
            <XmlDataProvider x:Key="PersonalData" Source="Model\Mitarbeiter.xml" XPath="Mitarbeiter" />
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1*"/>
            </Grid.RowDefinitions>
            <ComboBox Grid.Row="0" x:Name="cmbMitarbeiter" HorizontalAlignment="Left" Margin="10,10,0,0" 
                      VerticalAlignment="Top" Width="120" DisplayMemberPath="@PersonalID" 
                      ItemsSource="{Binding Source={StaticResource PersonalData}, XPath=./Person}" 
                      SelectedValuePath="@Vorname"
                      SelectedValue="{Binding SelectedVornameValue}"
                      />
            <Grid Grid.Row="1" DataContext="{Binding SelectedItem, ElementName=cmbMitarbeiter}">
                <TextBox Text="{Binding Vorname}"/>
            </Grid>
        </Grid>
    </Window>
    MainViewModel.vb
    Code:
    Imports System.ComponentModel
    Imports System.Xml
    Public Class MainViewModel : Implements INotifyPropertyChanged
    
        Public Sub New()
    
        End Sub
    
        Public Sub New(Vorname As String)
            Me.SelectedVornameValue = _SelectedVornameValue
        End Sub
    
        Private _SelectedVornameValue As String
        Public Property SelectedVornameValue As String
            Get
                Return _SelectedVornameValue
            End Get
            Set(ByVal value As String)
                _SelectedVornameValue = value
                RaiseProp("SelectedVornameValue")
            End Set
        End Property
    
        Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
    
    
        Public Sub RaiseProp(ByVal Propertie As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(Propertie))
        End Sub
    
    
    End Class
    Mitarbeiter.xml
    Code:
    <?xml version="1.0" encoding="utf-8" ?>
    <Mitarbeiter>
      <Person PersonalID="1" Vorname="Fritz" Nachname="Meier" />
      <Person PersonalID="2" Vorname="Max" Nachname="Mustermann" />
      <Person PersonalID="3" Vorname="Heinz" Nachname="Müller" />
    </Mitarbeiter>
    Where did I made a fault?

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Bind Textbox to Combobox in WPF (MVVM)

    You wouldn't bind controls to each other. A control should only be bound to a property of the view model. If two controls interact then they may be bound to the same property but they are still both bound to the view model.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3
    PowerPoster gep13's Avatar
    Join Date
    Nov 2004
    Location
    The Granite City
    Posts
    21,963

    Re: Bind Textbox to Combobox in WPF (MVVM)

    Hello,

    Since I have been digging into this some more, I thought I would give this a try, and this is what I have come up with.

    First of all, rather than load directly from the XML file, I created a Person class, which would be my Model:

    Code:
    Public Class Person
        Private _personalId As Integer
        Public Property PersonalId() As Integer
            Get
                Return _personalId
            End Get
            Set(ByVal value As Integer)
                _personalId = value
            End Set
        End Property
    
        Private _vorName As String
        Public Property VorName() As String
            Get
                Return _vorName
            End Get
            Set(ByVal value As String)
                _vorName = value
            End Set
        End Property
    
        Private _nachName As String
        Public Property NachName() As String
            Get
                Return _nachName
            End Get
            Set(ByVal value As String)
                _nachName = value
            End Set
        End Property
    
    End Class
    Then I created a ViewModel which uses this Model:

    Code:
    Imports System.ComponentModel
    Imports System.Collections.ObjectModel
    
    Public Class MainViewModel : Implements INotifyPropertyChanged
    
        Public Sub New()
            Me.People = New ObservableCollection(Of Person)()
            Me.People.Add(New Person With {.PersonalId = 1, .VorName = "Bob", .NachName = "Smith"})
            Me.People.Add(New Person With {.PersonalId = 2, .VorName = "Bill", .NachName = "Jones"})
            Me.People.Add(New Person With {.PersonalId = 3, .VorName = "James", .NachName = "Miller"})
        End Sub
    
        Private _people As ObservableCollection(Of Person)
        Public Property People As ObservableCollection(Of Person)
            Get
                Return _people
            End Get
            Set(ByVal value As ObservableCollection(Of Person))
                _people = value
                OnPropertyChanged("People")
            End Set
        End Property
    
        Private _selectedPerson As Person
        Public Property SelectedPerson() As Person
            Get
                Return _selectedPerson
            End Get
            Set(ByVal value As Person)
                _selectedPerson = value
                OnPropertyChanged("SelectedPerson")
            End Set
        End Property
    
        Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    
        ' Create the OnPropertyChanged method to raise the event 
        Protected Sub OnPropertyChanged(ByVal name As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
        End Sub
    End Class
    In the constructor I have just "faking" the creation of the people, but this is where you would put the work of loading the values from the XML file that you have.

    Then, within the constructor for the View, I put this:

    Code:
    Class MainWindow 
        Sub New()
    
            ' This call is required by the designer.
            InitializeComponent()
    
            ' Add any initialization after the InitializeComponent() call.
            Me.DataContext = New MainViewModel()
        End Sub
    End Class
    This could have been done in the XAML as well.

    Finally, the View then looks like this:

    Code:
    <Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="150" Width="150">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1*"/>
            </Grid.RowDefinitions>
            <ComboBox Grid.Row="0" x:Name="cmbMitarbeiter" 
                      HorizontalAlignment="Left" 
                      Margin="10,10,0,0" 
                      VerticalAlignment="Top" 
                      Width="120" 
                      DisplayMemberPath="PersonalId" 
                      SelectedValuePath="PersonalId" 
                      ItemsSource="{Binding People, Mode=OneWay}" 
                      SelectedItem="{Binding SelectedPerson}"
                      />
            <Grid Grid.Row="1" DataContext="{Binding SelectedPerson}">
                <StackPanel>
                    <TextBox Text="{Binding VorName}"/>
                    <TextBox Text="{Binding NachName}"/>
                </StackPanel>
            </Grid>
        </Grid>
    </Window>
    Notice, both portions of UI are binding to the ViewModel, rather than to each other.

    John, what are your thoughts on this? Good? Bad?

    Hope this helps!

    Gary

  4. #4
    PowerPoster gep13's Avatar
    Join Date
    Nov 2004
    Location
    The Granite City
    Posts
    21,963

    Re: Bind Textbox to Combobox in WPF (MVVM)

    Hi Moritz83,

    I just wanted to check...

    Did the above help you? Or are you still having problems?

    Gary

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width