0

Silverlightで独自の MVVM の例を作成するための基礎として、Silverlight の Model View View-Model (MVVM)という記事を使用しています。

私は以下のすべての部分を持っています:

  • メインページ(すべてをロード)
  • 表示(バインディングを含む XAML ファイル)
  • モデル(偽の List コレクションを生成する Customer クラス)
  • ModelView (INotifyPropertyChanged を継承し、View が必要とする 2 つのフィールドの PropertyChanged を持っています)

私のメインページでは:

  • ビューモデルを作成する
  • ViewModelViewのDataContextにバインドする
  • モデルの作成(顧客)

しかし、ModelView をモデルに接続するにはどうすればよいでしょうか。どうにかして CustomerViewModel に顧客のモデルを挿入する必要があるように感じますが、そうですか? しかし、どのように正確に?この MVVM の例を完成させるための次のステップは何ですか。これにより、MVVM パターンの利点を使い始めることができます。たとえば、モデルをテスト モデルに交換したり、ビューを新しいビューに交換したりします。


MainPage.xaml.cs: ViewModel を作成し、View を ViewModel にアタッチします。

using System.Windows.Controls;
using System.Collections.Generic;

namespace TestMvvm345
{
    public partial class MainPage : UserControl
    {
        private CustomerViewModel customerData;

        public MainPage()
        {
            InitializeComponent();

            customerData = new CustomerViewModel();
            customerHeaderView.DataContext = customerData;
            List<Customer> customers = Customer.GetCustomers();
        }
    }
}

MainPage.xaml: メイン ページのコンテキスト内でビューを表示します。

<UserControl x:Class="TestMvvm345.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:TestMvvm345"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel HorizontalAlignment="Left">
            <local:CustomerHeaderView x:Name="customerHeaderView" Margin="10"/>
        </StackPanel>
    </Grid>
</UserControl>

CustomerViewModel.xaml: ビューモデル

using System.ComponentModel;

namespace TestMvvm345
{
    public class CustomerViewModel : INotifyPropertyChanged
    {
        private string firstName;
        private string lastName;

        public string FirstName
        {
            get { return firstName; }
            set
            {
                firstName = value;
                RaisePropertyChanged("FirstName");
            }
        }

        public string LastName
        {
            get { return lastName; }
            set
            {
                lastName = value;
                RaisePropertyChanged("LastName");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

CustomerHeaderView.xaml ビュー

<UserControl x:Class="TestMvvm345.CustomerHeaderView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel HorizontalAlignment="Left">
            <ListBox x:Name="CustomerList" ItemsSource="{Binding}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock
                            Text="{FirstName}"/>
                            <TextBlock
                            Text="{LastName}"/>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </StackPanel>
    </Grid>
</UserControl>

モデルのCustomers.cs

using System;
using System.Collections.Generic;

namespace TestMvvm345
{
    public class Customer
    {
        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int NumberOfContracts { get; set; }

        public static List<Customer> GetCustomers()
        {
            List<Customer> customers = new List<Customer>();
            customers = new List<Customer>();
            customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", NumberOfContracts = 23 });
            customers.Add(new Customer { FirstName = "Jane", LastName = "Smith", NumberOfContracts = 22 });
            customers.Add(new Customer { FirstName = "John", LastName = "Tester", NumberOfContracts = 33 });
            customers.Add(new Customer { FirstName = "Robert", LastName = "Smith", NumberOfContracts = 2 });
            customers.Add(new Customer { FirstName = "Hank", LastName = "Jobs", NumberOfContracts = 5 });
            return customers;
        }
    }
}
4

1 に答える 1

1

ViewModel の使用方法は多少異なります。私の場合、実際には Model クラスをラップして、ほとんどのデータをモデルに渡します。そうすれば、モデル内のすべての標準的なビジネス ルールは、想定どおりにすぐに機能します。ViewModel は、データ バインディングやその他の UI の目的で実際に必要なプロパティのみを公開します。さらに、ViewModel には、データ バインディングに使用される他のプロパティ/メソッドが含まれる場合があります。

したがって、顧客の例を使用して: namespace TestMvvm345 { public class CustomerViewModel : INotifyPropertyChanged {

    private Customer _model;
    public Customer Model
    {
        get
        { return _model; }
        set
        {
            if (_model != null)
                Model.PropertyChanged -= Model_PropertyChanged;

            _model = value;

            if (_model != null)
                Model.PropertyChanged += Model_PropertyChanged;
        }
    }

    void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        RaisePropertyChanged(e.PropertyName);
        if (e.PropertyName == "FirstName" || e.PropertyName == "LastName")
            RaisePropertyChanged("FullName");
    }

    public string FirstName
    {
        get { return Model.FirstName; }
        set { Model.FirstName = value; }
    }

    public string LastName
    {
        get { return Model.LastName; }
        set { Model.LastName = value; }
    }

    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }


    public static IList<CustomerViewModel> GetCustomers()
    {
        var result = new List<CustomerViewModel>();
        var customers = Customer.GetCustomers();
        foreach (var customer in customers)
        {
            result.Add(new CustomerViewModel() { Model = customer });
        }
        return result;
    }
    public event PropertyChangedEventHandler PropertyChanged;

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


public class Customer : INotifyPropertyChanged
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int NumberOfContracts { get; set; }

    public static List<Customer> GetCustomers()
    {
        List<Customer> customers = new List<Customer>();
        customers = new List<Customer>();
        customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", NumberOfContracts = 23 });
        customers.Add(new Customer { FirstName = "Jane", LastName = "Smith", NumberOfContracts = 22 });
        customers.Add(new Customer { FirstName = "John", LastName = "Tester", NumberOfContracts = 33 });
        customers.Add(new Customer { FirstName = "Robert", LastName = "Smith", NumberOfContracts = 2 });
        customers.Add(new Customer { FirstName = "Hank", LastName = "Jobs", NumberOfContracts = 5 });
        return customers;
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

}

UI で、次のコードを使用してバインドします。 customerHeaderView.DataContext = CustomerViewModel.GetCustomers();

ViewModel のコードは多少大きくなりますが、基本クラスに多くのコードを配置でき、Model に渡されるすべてのプロパティはまったく同じです (T4 テンプレートを考えてください)。

于 2009-03-31T13:26:49.230 に答える