Как я могу подключить ModelView к модели в этом примере Silverlight MVVM? - PullRequest
0 голосов
/ 31 марта 2009

Я использую статью Модель представления модели (MVVM) в Silverlight в качестве основы для создания собственного примера MVVM в Silverlight.

У меня есть все кусочки ниже:

  • главная страница (загружает все)
  • Просмотр (файл XAML с привязками)
  • Модель (класс Customer, генерирующий поддельную коллекцию List)
  • ModelView (наследует INotifyPropertyChanged и имеет PropertyChanged для двух полей, которые нужны View)

На моей главной странице я:

  • создать ViewModel
  • привязать ViewModel к DataContext из View
  • создать модель (клиенты)

Но как мне теперь подключить 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: ViewModel

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

1 Ответ

1 голос
/ 31 марта 2009

Способ использования ViewModel несколько отличается. В моем случае это фактически обёртывает класс Model, передавая большую часть данных в модель. Таким образом, все стандартные бизнес-правила в модели по-прежнему работают так, как они должны прямо сейчас. ViewModel предоставляет только те свойства, которые действительно необходимы для привязки данных или других целей пользовательского интерфейса. Кроме того, ViewModel может содержать другие свойства / методы, используемые для привязки данных.

Итак, используя ваш пример клиента: пространство имен TestMvvm345 { открытый класс 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
}

}

Теперь в вашем пользовательском интерфейсе вы выполняете привязку, используя следующий код: customerHeaderView.DataContext = CustomerViewModel.GetCustomers ();

Код в ViewModel действительно становится несколько большим, но многое может быть помещено в базовый класс, и все свойства, которые идут в Model, абсолютно одинаковы (например, шаблон T4).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...