mvvm 튜토리얼
mvvm 시작하기
수색…
비고
이 절에서는 mvvm이 무엇인지, 그리고 왜 개발자가 mvvm을 사용하고자하는지에 대한 개요를 제공합니다.
또한 mvvm 내의 큰 주제를 언급하고 관련 주제에 링크해야합니다. mvvm에 대한 문서가 새롭기 때문에 이러한 관련 주제의 초기 버전을 만들어야 할 수도 있습니다.
C # MVVM 요약 및 전체 예제
개요:
MVVM 은 Model , View 및 ViewModel 의 세 가지 구성 요소로 표현되는 아키텍처 패턴입니다. 이 세 가지 레이어를 이해하려면 각 레이어를 간단히 정의하고 함께 작동하는 방법에 대한 설명이 필요합니다.
모델 은 비즈니스 로직을 주도하는 계층입니다. ViewModel에서 사용 하기 위해 모든 데이터 소스의 정보를 검색하고 저장 합니다 .
ViewModel 은 보기 와 모델 사이의 다리 역할을하는 계층입니다. 모델 의 원시 데이터를 뷰 의 표시 가능한 형식으로 변환 할 수도 그렇지 않을 수도 있습니다. 예제 변환은 모델에서 뷰의 'True'또는 'False'문자열에 대한 부울 플래그입니다.
보기 는 소프트웨어 인터페이스 (예 : GUI)를 나타내는 계층입니다. 그 역할은 사용자에게 뷰 모델의 정보를 표시하고, 다시 뷰 모델에 대한 정보의 변경을 전달하는 것이다.
이 세 가지 구성 요소는 다음과 같은 방식으로 서로 참조하여 함께 작동합니다.
- View 는 ViewModel을 참조 합니다 .
- ViewModel 은 모델을 참조합니다.
View 와 ViewModel 은 Data Bindings 라고하는 양방향 통신이 가능하다는 점에 유의해야 합니다 .
양방향 통신 (데이터 바인딩)의 주요 요소는 INotifyPropertyChanged 인터페이스입니다.
이 메커니즘을 이용하면 뷰 는 사용자 입력을 통해 ViewModel 의 데이터를 수정할 수 있으며 ViewModel 은 모델의 프로세스 또는 리포지토리의 업데이트 된 데이터를 통해 업데이트 된 데이터로 뷰 를 업데이트 할 수 있습니다.
MVVM 아키텍처는 각 계층 에 대한 관심 의 분리에 중점을 둡니다. 레이어를 분리하면 다음과 같은 이점이 있습니다.
- 모듈성 : 각 레이어의 내부 구현은 다른 레이어에 영향을주지 않고 변경하거나 교체 할 수 있습니다.
- 증가 테스트 용이성 : 각 층은 뷰 모델의 코드는보기의 코드 숨김로 작성이 불가능합니다 가짜 데이터와 테스트 단위가 될 수 있습니다.
빌드 :
솔루션에서 Model , ViewModel 및 View의 세 가지 새 폴더를 만들고 원래 MainWindow.xaml
삭제하여 새로운 시작을 얻으십시오.
각각 별도의 레이어에 해당하는 세 개의 새 항목을 만듭니다.
- Model 폴더를 마우스 오른쪽 단추로 클릭하고
HelloWorldModel.cs
라는 클래스 항목을 추가합니다. - ViewModel 폴더를 마우스 오른쪽 단추로 클릭하고
HelloWorldViewModel.cs
라는 클래스 항목을 추가하십시오. - View 폴더를 마우스 오른쪽 단추로 클릭하고
HelloWorldView.xaml
이라는 WPF (Window (창)) 항목을 추가합니다.
새 보기 를 가리 키도록 App.xaml
변경
<Application x:Class="MyMVVMProject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyMVVMProject"
StartupUri="/View/HelloWorldView.xaml">
<Application.Resources>
</Application.Resources>
</Application>
ViewModel :
먼저 ViewModel 을 빌드하는 것으로 시작하십시오. 클래스는 INotifyPropertyChanged
인터페이스를 구현하고 PropertyChangedEventHandler
이벤트를 선언하고 이벤트를 발생시키는 메서드를 만들어야합니다 (원본 : MSDN : 속성 변경 알림 구현 방법 ). 그런 다음 속성과 해당 속성을 선언하고 속성의 set
접근 자에서 OnPropertyChanged()
메서드를 호출해야합니다. 아래 예제의 생성자는 모델 이 ViewModel에 데이터를 제공함을 입증하는 데 사용됩니다.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using MyMVVMProject.Model;
namespace MyMVVMProject.ViewModel
{
// Implements INotifyPropertyChanged interface to support bindings
public class HelloWorldViewModel : INotifyPropertyChanged
{
private string helloString;
public event PropertyChangedEventHandler PropertyChanged;
public string HelloString
{
get
{
return helloString;
}
set
{
helloString = value;
OnPropertyChanged();
}
}
/// <summary>
/// Raises OnPropertychangedEvent when property changes
/// </summary>
/// <param name="name">String representing the property name</param>
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public HelloWorldViewModel()
{
HelloWorldModel helloWorldModel = new HelloWorldModel();
helloString = helloWorldModel.ImportantInfo;
}
}
}
모델:
다음으로 모델을 빌드하십시오. 이전에 언급했듯이 모델 은 ViewModel 을 저장소에서 가져 와서 저장하기 위해 다시 저장소로 푸시하여 데이터를 제공합니다. 이것은 간단한 List<string>
반환하는 GetData()
메서드로 아래에서 설명합니다. 비즈니스 로직도이 계층에 적용되며 ConcatenateData()
메소드에서 볼 수 있습니다. 이 메서드는 이전에 "저장소"에서 반환 된 List<string>
에서 문장 "Hello, world!"를 작성합니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyMVVMProject.Model
{
public class HelloWorldModel
{
private List<string> repositoryData;
public string ImportantInfo
{
get
{
return ConcatenateData(repositoryData);
}
}
public HelloWorldModel()
{
repositoryData = GetData();
}
/// <summary>
/// Simulates data retrieval from a repository
/// </summary>
/// <returns>List of strings</returns>
private List<string> GetData()
{
repositoryData = new List<string>()
{
"Hello",
"world"
};
return repositoryData;
}
/// <summary>
/// Concatenate the information from the list into a fully formed sentence.
/// </summary>
/// <returns>A string</returns>
private string ConcatenateData(List<string> dataList)
{
string importantInfo = dataList.ElementAt(0) + ", " + dataList.ElementAt(1) + "!";
return importantInfo;
}
}
}
전망:
마지막으로 보기를 작성할 수 있습니다. 이 예제의 코드 뒤에 추가해야 할 것은 없지만 애플리케이션의 요구에 따라 달라질 수 있습니다. 그러나 XAML에 몇 줄이 추가되었습니다. Window
에는 ViewModel
네임 스페이스에 대한 참조가 필요합니다. 이 이름은 XAML 네임 스페이스 xmlns:vm="clr-namespace:MyMVVMProject.ViewModel"
매핑됩니다. 다음으로 Window에는 DataContext
필요합니다. 이것은 <vm:HelloWorldViewModel/>
로 설정됩니다. 이제 레이블 (또는 선택한 컨트롤)을 창에 추가 할 수 있습니다. 이 단계의 핵심은 레이블 내용으로 표시 할 ViewModel 의 속성에 바인딩 을 설정했는지 확인하는 것입니다. 이 경우 {Binding HelloString}
입니다.
후자의 경우 OnPropertyChanged()
메서드는 PropertyChangedEvent
를 PropertyChangedEvent
에서만 가져 OnPropertyChanged()
값이 변경되었다는 알림을 View 에서받지 않으므로 필드가 아닌 속성에 바인딩하는 것이 중요합니다. 들.
<Window x:Class="MyMVVMProject.View.HelloWorldView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyMVVMProject.View"
xmlns:vm="clr-namespace:MyMVVMProject.ViewModel"
mc:Ignorable="d"
Title="HelloWorldView" Height="300" Width="300">
<Window.DataContext>
<vm:HelloWorldViewModel/>
</Window.DataContext>
<Grid>
<Label x:Name="label" FontSize="30" Content="{Binding HelloString}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Window>