2

MVVM パターンの ViewModel を正確に作成する方法を誰かに説明してもらえますか。http://msdn.microsoft.com/en-us/magazine/dd419663.aspxのチュートリアルを理解しようとしましたが、コードで何が起こっているのか正確に理解できませんでした。

ローカル データベースとの間でユーザーを取得および追加し、それらをビューに表示するための基本的なアプリケーションを作成するとします。ViewModel の外観とその RelayCommands の作成方法。まず、なぜ変数を 2 回設定するのでしょうか。

編集:これまでの助けに感謝します。もう 1 つわからないことがあります。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);
                }));
        }
    }
}

Csharp でビューのコードを使用して ViewModel を View にバインドする方法を見つけましたが、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();
    }
}

View と ViewModel の間のバインディングに関していくつか質問があります。このタイプのバインディングを使用することの長所と短所は何ですか? データベースを使用する場合、バインドする最良の方法は何ですか?

  1. これはViewModelとModelがどのように見えるかです
  2. 生徒を ObservableCollection に追加するための RelayCommand を作成する方法
  3. なぜ私たちは物事を最初に非公開で設定し、次に公に設定するのですか [回答済み]
  4. View を ViewModel に、またその逆にバインドする方法
4

1 に答える 1

3

プロパティ セッターでは、新しい値が古い値と等しいかどうかを確認する必要があります。等しい場合は、返して 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 light を使用しているように見えるので、コード スニペットを試す必要があります。これらにより、プロパティの作成が非常に簡単になります。mvvvminpc と入力してから、タブを 2 回押します。次に、強調表示された部分に入力し、終了するまでタブを押します。

ビューをビューモデルにバインドするには、いくつかの方法があります。アンチパターンであることはわかっていますが、ロケーターを使用できます。基本的な考え方は、viewmodel をビューのデータコンテキストとして設定することです。

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>
于 2013-11-14T20:25:19.610 に答える