3

I'm a newbie in the MVVM design patter I'm trying to create a simple app where a list of students is shown in the main window and I want the user to be able to add a new student to the list I have accomplished the binding of the observable collection where the students' data are but how can I create a new user by fetching the data from the textboxes and using them as a parameter in a command

Here is my View

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="2*"/>
        <RowDefinition Height="2*"/>
        <RowDefinition Height="2*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <TextBlock x:Name="NameTextBlock"
               Text="Name"
               Style="{StaticResource TextBlockTextStyle}"/>
    <TextBlock x:Name="SurnameTextBlock"
               Grid.Row="1"
               Text="Surname"
               Style="{StaticResource TextBlockTextStyle}"/>
    <TextBlock x:Name="AgeTextBlock"
               Grid.Row="2"
               Text="Age"
               Style="{StaticResource TextBlockTextStyle}"/>
    <TextBox x:Name="NameTextBox"
             Grid.Column="1"
             Style="{StaticResource TextBoxTextStyle}"/>
    <TextBox x:Name="SurnameTextBox"
             Grid.Row="1"
             Grid.Column="1"
             Style="{StaticResource TextBoxTextStyle}"/>
    <TextBox x:Name="AgeTextBox"
             Grid.Row="2"
             Grid.Column="1"
             Style="{StaticResource TextBoxTextStyle}"/>
    <ListBox x:Name="StudentListBox"
             Grid.ColumnSpan="2"
             Grid.Row="4"
             Style="{StaticResource ListBoxStyle}"
             ItemsSource="{Binding StudentList}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Name}"
                               Style="{StaticResource TextBlockTextStyle}"/>
                    <TextBlock Text="{Binding Surname}"
                               Grid.Column="1"
                               Style="{StaticResource TextBlockTextStyle}"/>
                    <TextBlock Text="{Binding Age}"
                               Grid.Column="2"
                               Style="{StaticResource TextBlockTextStyle}"/>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Button x:Name="AddButton"
            Grid.Row="7"
            Grid.ColumnSpan="2"
            HorizontalAlignment="Center"
            Content="Add"
            Margin="7,7,7,7"
            Command="{Binding AddStudentCommand}"/>        
</Grid>

And here is my ViewModel

public class MainViewModel : ViewModelBase
{
    ObservableCollection<Student> studentList;
    public MainViewModel()
    {
        //populate some sample data
        studentList = new ObservableCollection<Student>()
        {
            new Student(){Name="John", Surname="Smith", Age="28"},
            new Student(){Name="Barbara", Surname="Anderson", Age="23"}
        };
    }

    public ObservableCollection<Student> StudentList
    {
        get { return studentList; }
        set { RaisePropertyChanged("studentList"); }
    }

    Student selectedPerson;
    public Student SelectedPerson
    {
        get { return selectedPerson; }
        set
        {
            selectedPerson = value;
            RaisePropertyChanged("SelectedPerson");
        }
    }

    private RelayCommand _addStudentCommand;
    public ICommand AddStudentCommand
    {
        get
        {
            return _addStudentCommand
                ?? (_addStudentCommand = new RelayCommand(() =>
                {
                    Student student = new Student();
                    // here should be the logic of defining the name, surname, 
                    // age and id of the newly created student
                    studentList.Add(student);
                }));
        }
    }

}

I am using MVVMLight in the current project and there are a lot of thing that I do not understand so please explain how I should pass the data of the textboxes and what exactly should happen in the command that it is being used.

Tell me to add more of the code if necessary.

EnvelopedDevil
  • 658
  • 1
  • 13
  • 29
  • Hey there :) As you've stated, you've not had much experience and don't understand much with MVVM, so although I could answer this question, I think the best thing I could do is provide you with a few links to watch : http://www.youtube.com/watch?v=BClf7GZR0DQ and http://channel9.msdn.com/blogs/kreekman/techdays-2010-understanding-the-model-view-viewmodel-pattern. The second video is from the guy who wrote MVVM-light. They basically cover the same material, but both bring a slightly different perspective! – Immortal Blue Nov 18 '13 at 08:29
  • @ImmortalBlue thanks for the videos it helped a lot – EnvelopedDevil Nov 18 '13 at 17:22

2 Answers2

5

What I would do is create some properties that the textboxes are bound to in the ViewModel. Like this for all three (in your viewmodel)

private string _Name;
    public string Name
    {
        get { return _Name; }
        set
        {
            _Name = value;
            RaisePropertyChanged("Name");
        }
    }

Then, in the XAML, bind the textbox's text to this:

<TextBox x:Name="NameTextBox"
             Text="{Binding Name}"
         Grid.Column="1"
         />

Finally in the AddStudent Command you reference the properties in the viewmodel that are bound to the textboxes.

private RelayCommand _addStudentCommand;
    public ICommand AddStudentCommand
    {
        get
        {
            return _addStudentCommand
                ?? (_addStudentCommand = new RelayCommand(() =>
                {
                    Student student = new Student();
                    student.Name = this.Name;
                    student.Surname = this.Surname;
                    student.Age = this.Age;
                    // here should be the logic of defining the name, surname, 
                    // age and id of the newly created student
                    _StudentList.Add(student);
                }));
        }
    }
Mike Schwartz
  • 2,182
  • 1
  • 17
  • 26
  • Just force of habit. Normally two-way binding would be needed if you were going to propagate changes back to the business object. I edited my post and omitted the two-way binding. – Mike Schwartz Nov 18 '13 at 17:46
  • Yes, and thanks for the code but I have a problem here - If I want to create a different class to hold my data how am I supposed to use it in any of the ViewModels and the commands – EnvelopedDevil Nov 19 '13 at 19:02
  • Well I was just giving you a basic example of what would work. You would have to give a more concrete example of what you are trying to attain. WPF is very flexible and you have plenty of options. – Mike Schwartz Nov 19 '13 at 19:18
  • Yes of course! Be sure to mark it as answered if I answered your question :) – Mike Schwartz Nov 20 '13 at 15:00
  • I have some technical issues with my pc so I will be out of the developing enviromnt for some time, Thanks for the help and I am sorry put I don't have the reputation to vote the answe up – EnvelopedDevil Nov 20 '13 at 19:19
-1

(cheekily posted from my comment)

As you've stated, you've not had much experience and don't understand much with MVVM, so although I could answer this question, I think the best thing I could do is provide you with a few links to watch :

youtube.com/watch?v=BClf7GZR0DQ

and

channel9.msdn.com/blogs/kreekman/

The second video is from the guy who wrote MVVM-light.

They basically cover the same material, but both bring a slightly different perspective!

FoldFence
  • 2,674
  • 4
  • 33
  • 57
Immortal Blue
  • 1,691
  • 13
  • 27
  • 1
    SO is a place to seek help from others who "know" and share knowledge. "so although I could answer this question....." If we all took this attitude, we all should then just be learning from text books. – TheAppMentor Mar 04 '22 at 12:40