Model-View-View Model과 함께 이식 가능한 클래스 라이브러리 사용Using Portable Class Library with Model-View-View Model

.NET Framework를 사용 하 여 이식 가능한 클래스 라이브러리 모델-뷰 모델 (MVVM) 패턴을 구현 하 여 여러 플랫폼 간에 어셈블리를 공유 합니다.You can use the .NET Framework Portable Class Library to implement the Model-View-View Model (MVVM) pattern and share assemblies across multiple platforms.

중요

이식 가능한 클래스 라이브러리 프로젝트는.NET 구현의 매우 구체적인 하위 집합만 대상으로 하기 때문에 강력한 것이 좋습니다 새 응용 프로그램 개발에 사용을 합니다.Because Portable Class Library projects target only a very specific subset of .NET implementations, we strongly discourage their use in new application development. 권장 되는 대신.NET Standard 라이브러리를.NET 표준의 특정 버전을 지 원하는 모든.NET 구현을 대상으로 하는 경우The recommended replacement is a .NET Standard library, which targets all .NET implementations that support a specific version of the .NET Standard. 자세한 내용은 .NET 표준을 참조하세요.For more information, see .NET Standard.

MVVM은 내부 비즈니스 논리에서 사용자 인터페이스를 분리하는 응용 프로그램 패턴입니다.MVVM is an application pattern that isolates the user interface from the underlying business logic. 모델 및 보기 모델 클래스를 구현할 수는 이식 가능한 클래스 라이브러리Portable Class Library Visual Studio 2012에서 프로젝트를 만든 다음 다양 한 플랫폼에 대 한 사용자 지정 된 보기입니다.You can implement the model and view model classes in a 이식 가능한 클래스 라이브러리Portable Class Library project in Visual Studio 2012, and then create views that are customized for different platforms. 이 접근 방식을 사용하면 한 번만 데이터 모델과 비즈니스 논리를 작성하고, 다음 설명에서와 같이 .NET Framework, Silverlight, Windows Phone 및 Windows 8.x 스토어Windows 8.x Store 응용 프로그램의 해당 코드를 사용할 수 있습니다.This approach enables you to write the data model and business logic only once, and use that code from .NET Framework, Silverlight, Windows Phone, and Windows 8.x 스토어Windows 8.x Store apps, as shown in the following illustration.

플랫폼에서 MVVM 공유 어셈블리를 사용 하 여 이식 가능한 클래스 라이브러리를 보여 줍니다.

이 항목에서는 MVVM 패턴에 대 한 일반 정보를 제공 하지 않습니다.This topic does not provide general information about the MVVM pattern. 만 사용 하는 방법에 대 한 정보를 제공 이식 가능한 클래스 라이브러리Portable Class Library MVVM을 구현 합니다.It only provides information about how to use 이식 가능한 클래스 라이브러리Portable Class Library to implement MVVM. MVVM에 대 한 자세한 내용은 참조는 MVVM 퀵 스타트를 사용 하 여 Prism 라이브러리 5.0 WPF 용합니다.For more information about MVVM, see the MVVM Quickstart Using the Prism Library 5.0 for WPF.

MVVM을 지 원하는 클래스Classes That Support MVVM

대상 하는 경우는 .NET Framework 4.5.NET Framework 4.5, Windows 8.x 스토어 앱용 .NET.NET for Windows 8.x Store apps, Silverlight 또는 Windows Phone 7.5에 대 한 프로그램 이식 가능한 클래스 라이브러리Portable Class Library 프로젝트에 다음 클래스는 MVVM 패턴을 구현 하기 위한 사용할 수 있습니다:When you target the .NET Framework 4.5.NET Framework 4.5, Windows 8.x 스토어 앱용 .NET.NET for Windows 8.x Store apps, Silverlight, or Windows Phone 7.5 for your 이식 가능한 클래스 라이브러리Portable Class Library project, the following classes are available for implementing the MVVM pattern:

MVVM을 구현Implementing MVVM

MVVM을 구현 하려면 일반적으로 만든 모델과 뷰 모델을 이식 가능한 클래스 라이브러리Portable Class Library 때문에 프로젝트를 이식 가능한 클래스 라이브러리Portable Class Library 프로젝트 이식 가능 프로젝트를 참조할 수 없습니다.To implement MVVM, you typically create both the model and the view model in a 이식 가능한 클래스 라이브러리Portable Class Library project, because a 이식 가능한 클래스 라이브러리Portable Class Library project cannot reference a non-portable project. 동일한 프로젝트에서 또는 별도 프로젝트에서 모델 및 뷰 모델을 수 있습니다.The model and view model can be in the same project or in separate projects. 별도 프로젝트를 사용 하는 경우 모델 프로젝트에 뷰 모델 프로젝트에서 참조를 추가 합니다.If you use separate projects, add a reference from the view model project to the model project.

모델을 컴파일하여 모델 프로젝트를 확인 한 후 뷰가 포함 된 앱에서 해당 어셈블리를 참조 합니다.After you compile the model and view model projects, you reference those assemblies in the app that contains the view. 뷰는 뷰 모델만 상호 작용을 하는 경우 뷰 모델이 포함 된 어셈블리를 참조 해야 합니다.If the view interacts only with the view model, you only have to reference the assembly that contains the view model.

ModelModel

다음 예제에서는 수에 있는 간단한 모델 클래스는 이식 가능한 클래스 라이브러리Portable Class Library 프로젝트입니다.The following example shows a simplified model class that could reside in a 이식 가능한 클래스 라이브러리Portable Class Library project.

using System;

namespace SimpleMVVM.Model
{  
    public class Customer
    {
        public int CustomerID
        {
            get; 
            set;   
        }

        public string FullName
        {
            get;
            set;
        }

        public string Phone
        {
            get; 
            set;
        }
    }
}
Namespace SimpleMVVM.Model

    Public Class Customer
        Public Property CustomerID() As Integer
        Public Property FullName() As String
        Public Property Phone() As String
    End Class
End Namespace

다음 예에서는 채우기, 검색 및 데이터를 업데이트 하는 간단한 방법을 보여 줍니다는 이식 가능한 클래스 라이브러리Portable Class Library 프로젝트입니다.The following example shows a simple way to populate, retrieve, and update the data in a 이식 가능한 클래스 라이브러리Portable Class Library project. 실제 앱에서는 Windows Communication Foundation (WCF) 서비스와 같은 원본에서 데이터를 검색할 됩니다.In a real app, you would retrieve the data from a source such as a Windows Communication Foundation (WCF) service.

using System;
using System.Collections.Generic;
using System.Linq;

namespace SimpleMVVM.Model
{
    public class CustomerRepository
    {
        private List<Customer> _customers;

        public CustomerRepository()
        {
            _customers = new List<Customer>
            {
                new Customer(){ CustomerID = 1, FullName="Dana Birkby", Phone="394-555-0181"},
                new Customer(){ CustomerID = 2, FullName="Adriana Giorgi", Phone="117-555-0119"},
                new Customer(){ CustomerID = 3, FullName="Wei Yu", Phone="798-555-0118"}
            };
        }

        public List<Customer> GetCustomers()
        {
            return _customers;
        }

        public void UpdateCustomer(Customer SelectedCustomer)
        {
            Customer customerToChange = _customers.Single(c => c.CustomerID == SelectedCustomer.CustomerID);
            customerToChange = SelectedCustomer;
        }
    }
}
Namespace SimpleMVVM.Model
    Public Class CustomerRepository
        Private _customers As List(Of Customer)

        Public Sub New()
            _customers = New List(Of Customer) From
            {
                New Customer() With {.CustomerID = 1, .FullName = "Dana Birkby", .Phone = "394-555-0181"},
                New Customer() With {.CustomerID = 2, .FullName = "Adriana Giorgi", .Phone = "117-555-0119"},
                New Customer() With {.CustomerID = 3, .FullName = "Wei Yu", .Phone = "798-555-0118"}
            }
        End Sub

        Public Function GetCustomers() As List(Of Customer)
            Return _customers
        End Function

        Public Sub UpdateCustomer(SelectedCustomer As Customer)
            Dim customerToChange = _customers.Single(Function(c) c.CustomerID = SelectedCustomer.CustomerID)
            customerToChange = SelectedCustomer
        End Sub
    End Class
End Namespace

뷰 모델View Model

보기 모델에 대 한 기본 클래스는 MVVM 패턴을 구현 하는 경우에 자주 추가 됩니다.A base class for view models is frequently added when implementing the MVVM pattern. 다음 예제에서는 기본 클래스를 보여 줍니다.The following example shows a base class.

using System;
using System.ComponentModel;

namespace SimpleMVVM.ViewModel
{
    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }
    }
}
Imports System.ComponentModel

Namespace SimpleMVVM.ViewModel

    Public MustInherit Class ViewModelBase
        Implements INotifyPropertyChanged

        Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

        Protected Overridable Sub OnPropertyChanged(propname As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propname))
        End Sub
    End Class
End Namespace

구현 된 ICommand 인터페이스 MVVM 패턴을 사용 하 여 자주 사용 됩니다.An implementation of the ICommand interface is frequently used with the MVVM pattern. 다음 예제에서는 ICommand 인터페이스의 구현을 보여 줍니다.The following example shows an implementation of the ICommand interface.

using System;
using System.Windows.Input;

namespace SimpleMVVM.ViewModel
{
    public class RelayCommand : ICommand
    {
        private readonly Action _handler;
        private bool _isEnabled;

        public RelayCommand(Action handler)
        {
            _handler = handler;
        }

        public bool IsEnabled
        {
            get { return _isEnabled; }
            set
            {
                if (value != _isEnabled)
                {
                    _isEnabled = value;
                    if (CanExecuteChanged != null)
                    {
                        CanExecuteChanged(this, EventArgs.Empty);
                    }
                }
            }
        }

        public bool CanExecute(object parameter)
        {
            return IsEnabled;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            _handler();
        }
    }
}
Imports System.Windows.Input

Namespace SimpleMVVM.ViewModel

    Public Class RelayCommand
        Implements ICommand

        Private _isEnabled As Boolean
        Private ReadOnly _handler As Action

        Public Sub New(ByVal handler As Action)
            _handler = handler
        End Sub

        Public Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged

        Public Property IsEnabled() As Boolean
            Get
                Return _isEnabled
            End Get
            Set(ByVal value As Boolean)
                If (value <> _isEnabled) Then
                    _isEnabled = value
                    RaiseEvent CanExecuteChanged(Me, EventArgs.Empty)
                End If
            End Set
        End Property

        Public Function CanExecute(parameter As Object) As Boolean Implements ICommand.CanExecute
            Return IsEnabled
        End Function

        Public Sub Execute(parameter As Object) Implements ICommand.Execute
            _handler()
        End Sub

    End Class
End Namespace

다음 예제에서는 단순화 된 보기 모델을 보여 줍니다.The following example shows a simplified view model.

using System;
using System.Collections.Generic;
using SimpleMVVM.Model;

namespace SimpleMVVM.ViewModel
{
    public class CustomerViewModel : ViewModelBase
    {
        private List<Customer> _customers;
        private Customer _currentCustomer;
        private CustomerRepository _repository;

        public CustomerViewModel()
        {
            _repository = new CustomerRepository();
            _customers = _repository.GetCustomers();

            WireCommands();
        }

        private void WireCommands()
        {
            UpdateCustomerCommand = new RelayCommand(UpdateCustomer);
        }

        public RelayCommand UpdateCustomerCommand
        {
            get;
            private set;
        }

        public List<Customer> Customers
        {
            get { return _customers; }
            set { _customers = value; }
        }

        public Customer CurrentCustomer
        {
            get
            {
                return _currentCustomer;
            }

            set
            {
                if (_currentCustomer != value)
                {
                    _currentCustomer = value;
                    OnPropertyChanged("CurrentCustomer");
                    UpdateCustomerCommand.IsEnabled = true;
                }
            }
        }

        public void UpdateCustomer()
        {
            _repository.UpdateCustomer(CurrentCustomer);
        }
    }
}
Imports System.Collections.Generic
Imports SimpleMVVM.Model

Namespace SimpleMVVM.ViewModel

    Public Class CustomerViewModel
        Inherits ViewModelBase

        Private _customers As List(Of Customer)
        Private _currentCustomer As Customer
        Private _repository As CustomerRepository
        Private _updateCustomerCommand As RelayCommand

        Public Sub New()
            _repository = New CustomerRepository()
            _customers = _repository.GetCustomers()

            WireCommands()
        End Sub

        Private Sub WireCommands()
            UpdateCustomerCommand = New RelayCommand(AddressOf UpdateCustomer)
        End Sub

        Public Property UpdateCustomerCommand() As RelayCommand
            Get
                Return _updateCustomerCommand
            End Get
            Private Set(value As RelayCommand)
                _updateCustomerCommand = value
            End Set
        End Property

        Public Property Customers() As List(Of Customer)
            Get
                Return _customers
            End Get
            Set(value As List(Of Customer))
                _customers = value
            End Set
        End Property

        Public Property CurrentCustomer() As Customer
            Get
                Return _currentCustomer
            End Get
            Set(value As Customer)
                If _currentCustomer.Equals(value) Then
                    _currentCustomer = value
                    OnPropertyChanged("CurrentCustomer")
                    UpdateCustomerCommand.IsEnabled = True
                End If
            End Set
        End Property

        Public Sub UpdateCustomer()
            _repository.UpdateCustomer(CurrentCustomer)
        End Sub
    End Class
End Namespace

보기View

.NET Framework 4.5.NET Framework 4.5Windows 8.x 스토어Windows 8.x Store 앱, Silverlight 기반 앱 또는 Windows Phone 7.5 앱, 모델과 뷰 모델 프로젝트를 포함 하는 어셈블리를 참조할 수 있습니다.From a .NET Framework 4.5.NET Framework 4.5 app, Windows 8.x 스토어Windows 8.x Store app, Silverlight-based app, or Windows Phone 7.5 app, you can reference the assembly that contains the model and view model projects. 그런 다음 뷰 모델을 사용 하 여 상호 작용 하는 뷰를 만듭니다.You then create a view that interacts with the view model. 다음 예제에서는 검색 및 보기 모델의 데이터를에서 업데이트 하는 간단한 Windows Presentation Foundation (WPF) 앱을 보여 줍니다.The following example shows a simplified Windows Presentation Foundation (WPF) app that retrieves and updates data from the view model. Windows Phone Silverlight에서 유사한 뷰를 만들 수 있습니다 또는 Windows 8.x 스토어Windows 8.x Store 앱.You could create similar views in Silverlight, Windows Phone, or Windows 8.x 스토어Windows 8.x Store apps.

<Window x:Class="SimpleWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModels="clr-namespace:SimpleMVVM.ViewModel;assembly=SimpleMVVM.ViewModel"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <viewModels:MainPageViewModel x:Key="ViewModel" />
    </Window.Resources>
    <Grid DataContext="{Binding Source={StaticResource ViewModel}}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Height="23" Margin="5" HorizontalAlignment="Right" Grid.Column="0" Grid.Row="0" Name="textBlock2" 
                   Text="Select a Customer:" VerticalAlignment="Top" />
        <ComboBox Height="23" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="0" Name="CustomersComboBox" VerticalAlignment="Top" Width="173" 
                  DisplayMemberPath="FullName" SelectedItem="{Binding Path=CurrentCustomer, Mode=TwoWay}" ItemsSource="{Binding Path=Customers}" />
        <TextBlock Height="23" Margin="5" HorizontalAlignment="Right" Grid.Column="0" Grid.Row="1" Name="textBlock4" Text="Customer ID" />
        <TextBlock Height="23" Margin="5" HorizontalAlignment="Right" Grid.Column="0" Grid.Row="2" Name="textBlock5" Text="Name" />
        <TextBlock Height="23" Margin="5" HorizontalAlignment="Right" Grid.Column="0" Grid.Row="3" Name="textBlock9" Text="Phone" />
        <TextBlock Height="23" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="1" Name="CustomerIDTextBlock" 
                   Text="{Binding ElementName=CustomersComboBox, Path=SelectedItem.CustomerID}" />
        <TextBox Height="23" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="2" Width="219" 
                 Text="{Binding Path=CurrentCustomer.FullName, Mode=TwoWay}" />
        <TextBox Height="23" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="3" Width="219" 
                 Text="{Binding Path=CurrentCustomer.Phone, Mode=TwoWay}" />
        <Button
            Command="{Binding UpdateCustomerCommand}"
            Content="Update" Height="23" HorizontalAlignment="Right" Grid.Column="0" Grid.Row="4" 
            Name="UpdateButton" VerticalAlignment="Top" Width="75" />
    </Grid>
</Window>

참고자료See also