2013-11-14 7 views
2

Может кто-нибудь объяснить мне, как именно создать ViewModel для шаблона MVVM. Я попытался понять учебник здесь: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx, но мне не удалось понять, что именно происходит в коде.MVVM Создание ViewModel

Предположим, мы хотим создать базовое приложение о получении и добавлении людей из локальной базы данных и в их отображение в представлении. Как выглядит ViewModel и как создать для него RelayCommands. Во-первых, почему мы устанавливаем переменные дважды: один раз в частном порядке, а затем публично.

EDIT: Спасибо за помощь. У меня есть еще одна вещь, которую я не знаю, чтобы сделать - как связать View в ViewModel и НАОБОРОТ

Здесь есть Модель:

public class Student : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

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

    private string name; 
    private string surname; 
    private string age; 

    public string Name 
    { 
     get 
     { 
      return name; 
     } 
     set 
     { 
      name = value; 
      OnPropertyChanged("Name"); 
     } 
    } 

    public string Surname 
    { 
     get 
     { 
      return surname; 
     } 
     set 
     { 
      surname = value; 
      OnPropertyChanged("Surname"); 
     } 
    } 

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

и вот ViewModel:

public class MainViewModel : ViewModelBase 
{ 
    ObservableCollection<Student> studentList; 
    Student selectedPerson; 

    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; } 
    } 

    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(); 
        studentList.Add(student); 
       })); 
     } 
    } 
} 

Я нашел способ привязать ViewModel к представлению, используя некоторый код для представления в Csharp, но вопрос о том, как связать View с ViewModel, все еще на уме. Чтобы быть более конкретным, как создать нового ученика, используя значения, введенные пользователем в представлении.

Здесь показан вид в XAML-код

<Window x:Class="MVVMLight.View.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" 
    SizeToContent="WidthAndHeight"> 
<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> 

А вот мнение, в Csharp код

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = new MainViewModel(); 
    } 
} 

У меня есть некоторые вопросы, касающиеся связывания между видом и ViewModel: Каковы плюсы и минусы использования этого типа привязки? Каков наилучший способ привязки, если я собираюсь использовать базу данных?

  1. Это как ViewModel и модель должна выглядеть
  2. Как создать RelayCommand для добавления студента к ObservableCollection
  3. Почему мы устанавливаем вещи первой частной, а затем снова публично [Ответил]
  4. Как связать View с ViewModel и нАОБОРОТ
+0

ваш ViewModel будет иметь '' ObservableCollection и пара команд, таких как 'AddPersonCommand' и' RemovePersonCommand'. Какой у Вас вопрос? –

+1

Вы загрузили демонстрационный проект и немного просмотрели его? Как только я это сделал, большинство аспектов MVVM стало ясным для меня очень быстро. – Xaser

+0

@HighCore Мой вопрос - как определить те команды –

ответ

2

в ваших сеттеры собственности вы должны проверить, чтобы увидеть, если новое значение равно старому значению, если вы должны вернуться и не ели e событие PropertyChanged.

Что касается ваших вопросов:

  1. Да это выглядит нормально.
  2. Существует несколько способов настройки ваших команд реле.Я предпочитаю

    private RelayCommand<Student> _addStudentCommand; 
    public ICommand AddStudentCommand 
    { 
        get 
        { 
         return _addStudentCommand 
          ?? (_addStudentCommand = new RelayCommand<Student>((student) => 
           { 
            studentList.Add(student); 
           })); 
        } 
    } 
    

другой путь без прохождения в студенческом объекте

private RelayCommand _addStudentCommand; 
    public ICommand AddStudentCommand 
    { 
     get 
     { 
      return _addStudentCommand 
       ?? (_addStudentCommand = new RelayCommand(() => 
        { 
         Student student = new Student(); 
         studentList.Add(student); 
        })); 
     } 
    } 
  1. То есть, как свойства работают в .net, Вы можете использовать автоматические свойства, но так как вам нужно стрелять изменить уведомление в сеттере, вам нужно объявить поле, с которым будет работать свойство.

Также, поскольку вы используете свет mvvm, вы должны попробовать фрагменты кода. Они делают свойства очень легкими в создании. введите mvvvminpc, затем дважды нажмите вкладку. затем заполните выделенную часть и нажмите вкладку, пока вы не закончите.

Вы можете связать View To Viewmodel несколькими способами. Я знаю, что это Антипаттерн, но вы можете использовать локатор. Основная идея заключается в том, чтобы установить viewmodel в качестве вида datacontext.

public class Locator 
{ 
    public Viewmodel1 Viewmodel1 
    { 
     return new Viewmodel1(); 
    } 
} 

Вы тогда в вас app.xaml добавить этот класс

<Application.Resources> 
    <Locator x:key="VMLocator" /> 
</Application.Resources> 

Затем на ваш взгляд, в XAML

<Page DataContext="{Binding Source="{StaticResource VMLocator}" Path=ViewModel1}"> 

</Page> 
+0

и как должен блокироваться класс RelayCommand? EDIT: Я не использую структуру MVVM light, просто подход, который использует инфраструктура –

+1

@GeorgeAnastasov Я не понимаю, что RelayCommand и RelayCommand включены в набор инструментов mvvm light. Преимущество RelayCommand заключается в том, что вам не нужно создавать собственную реализацию ICommand. – jfin3204

+0

@GeorgeAnastasov Вы увидите RelayCommand в коде, который вы просматривали, или в любой инфраструктуре mvvm. Вам не нужно писать свои собственные. – bland

Смежные вопросы