0
votes

I am trying to work MVVM. I created a model with 3 properties (ModelClass), and in my view model i have an observable collection of ModelClasses. In the view i bind a list to the observable collection in my VM. the list is a template of 3 textboxes.

how can i bind the textbox to a specific property in my model?

say the model class is called Person and has name, age and country as properties, the view model has a collection of persons, the view has a list bound to the person list (itemssource..). i don't know how to make a textbox in list bound to name, age and country of the person model.

3
Read the manual, please. Data Binding, Data TemplatingH.B.

3 Answers

2
votes

As per your query,i build the sample app and it's perfectly working for me.Details are furnished below.

PersonViewModel.cs

  internal class PersonViewModel{

    public ObservableCollection<PersonModel> PersonCollection { get; set; }

    public PersonViewModel()
    {
        //This data will load as the default person from the model attached to the view
        PersonCollection = new ObservableCollection<PersonModel>();
        PersonCollection.Add(new PersonModel { Name = "John", Age= 24, Country = "Canada"});
        PersonCollection.Add(new PersonModel { Name = "David", Age = 25, Country = "United States"});
        PersonCollection.Add(new PersonModel { Name = "Prajin", Age = 28, Country = "Japan"});
    }
}

PersonView.xaml

<Window x:Class="MVVM.PersonView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MVVM Demostration" Height="297" Width="480"
    xmlns:local="clr-namespace:MVVM.ViewModel">
<Window.DataContext>
    <local:PersonViewModel />
</Window.DataContext>

<Grid Margin="10">
    <ListBox ItemsSource="{Binding PersonCollection}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Path=Name}" Margin="5" Grid.Column="0" FontSize="14" />                        
                    <TextBlock Text="{Binding Path=Age}" Margin="5" Grid.Column="1" FontSize="14" />
                    <TextBlock Text="{Binding Path=Country}" Margin="5" Grid.Column="2" FontSize="14"/>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

Person.cs

 internal class PersonModel : System.ComponentModel.INotifyPropertyChanged
{
    private string name;
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            OnPropertyChanged("Name");
        }
    }

    private int age;
    public int Age
    {
        get { return age; }
        set
        {
            age = value;
            OnPropertyChanged("Age");
        }
    }

    private string country;
    public string Country
    {
        get { return country; }
        set
        {
            country = value;
            OnPropertyChanged("Country");
        }
    }

    #region INotifyPropertyChanged Members

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
    }

    #endregion
}
1
votes

You need to change the ItemTemplate of the list to bind the the properties:

<ListView ItemsSource="{Binding PersonsList}" > 
    <ListView.ItemTemplate> 
        <DataTemplate> 
           <StackPanel Orientation="Horizontal"> 
                  <TextBlock Text="{Binding Path=Name}" VerticalAlignment="Center" FontSize="14" /> 
                  <TextBlock Text="{Binding Path=Age}" VerticalAlignment="Center" FontSize="14" /> 
           </StackPanel> 
        </DataTemplate> 
     </ListView.ItemTemplate> 
  </ListView>
0
votes

Create a ListBox and bind your collection of objects to its ItemsSource. Here, Persons is the collection from your ViewModel.

<ListBox ItemsSource="{Binding Persons}" />

Then create a DataTemplate for your object type.

<DataTemplate DataType="{x:Type local:Person} >
    <TextBox Text="{Binding Name}"/>
    <TextBox Text="{Binding Age}"/>
    etc...
</DataTemplate>

Where "local" is an xml namespace alias for the namespace containing the Person type.

Put this DataTemplate in your window's resources (Window.Resources).