* 비쥬얼 스튜디오에 WPF가 있었다. 문득 궁금해졌다. 그래서 찾아 보았다.
** 실버라이트 기반으로 만든 어플리케이션 어쩌구 저쩌구..라고 그런다; 중요한것은 이것이 아니다. 실버라이트랑 비슷한 개발 형태를 뛴다는 것은 중요하다. 즉, 개발시 디자이너파일이 따로 분리 되어 있다.
** 웹개발자들은 MVC에 익숙하다. 하지만 이벤트 기반의 어플리케이션은 MVC로 분리는 말이 맞지가 않다. 그렇다 이벤트 기반의 어플리케이션 개발시 사용하는 패턴이 MVVM이다.
** 물론 다른 패턴도 있겠지만 아무튼 이렇다는게 중요하다.
** 그래서 MVVM에 대해서 공부하다 보니 여러개가 나온다. MVVM, Command, Behavior 이래 용어가 나온다. 그래 이게 중요한다.
* MVVM Light Toolkit 이란?
** 프레임워크이다. MVVM 패턴을 준수하여 개발된 프레임워크이다.
** 다운로드 URL : http://www.galasoft.ch/mvvm/
* 디자이너는 어떻게 작업을 하나?
** 비주얼 스튜디오 패키지에 보면은 Blend for Visual Studio가 있다 그것을 사용하여 개발하면 된다.
** blend를 사용하여 view파일을 만들어 내면, 개발자는 ViewModel을 대응하여 만들어 내면 된다.
** blend4 sdk for wpf : http://www.microsoft.com/ko-kr/download/details.aspx?id=10801
** nuget : http://www.nuget.org/packages/Microsoft.Expression.Blend.SDK.WPF/4.0.0
* 간단한 예제
** URL : http://sirars.com/tag/mvvm-light-toolkit/
*** 위에 분께서 아주 친절하게 잘 성명 하였다. 난 그것을 보고 그대로 만들었을뿐...(-_ㅡ)a
1. MVVM Light를 설치하고, 비주얼 스튜디오을 열고, MVVM Light WPF 프로젝트를 생성합니다. ViewModel 폴더를 보면은
ViewModelLocator과 MainViewModel이 있는것을 볼수 있다. ViewModelLocator은 ViewModel들을 가지고 있다가 찾아 주는 역할을 한다. 즉 View에서 해당 ViewModelLocator을 보고, 선언 되어 있는 ViewModel을 찾아온다.
그럼 ViewModel을 생성해보겠다. "SenderViewModel" 클래스를 ViewModel폴더에 추가한다.
public class SenderViewModel : ViewModelBase
{
public RelayCommand OnClickCommand { get; set; }
private string _textBoxText;
public string TextBoxText
{
get { return _textBoxText; }
set
{
_textBoxText = value;
RaisePropertyChanged("TextBoxText");
}
}
public SenderViewModel()
{
OnClickCommand = new RelayCommand(OnClickCommandAction, null);
}
private void OnClickCommandAction()
{
var viewModelMessage = new ViewModelMessage()
{
Text = TextBoxText
};
Messenger.Default.Send(viewModelMessage);
}
}
2. 여기서 만들 프로그램은 두개의 유저컨트롤이 String을 서로 주고 받아야 된다. 그렇게 하기위해 String을 주고 받아 줄 클래스를 작성 할것이다. 먼저, Messages라는 폴더를 추가한다. 그후, ViewModelMessage 클래스를 선언한다.
public class ViewModelMessage : MessageBase
{
public string Text { get; set; }
}
3. 자, 그럼 ViewModel에서 이벤트도 정의 되었으니 인제는 View를 만들어 보도록 한다. C#은 이벤트 프로그램을 기반을 두고 있다. 그러므로 화면단위로 분리 하는 것이 아니라, 컨트롤 단위로 보는것이 맞다. 그렇게 설계하는 것이 맞고, 가능할것이다. 그러므로 여기서 View라고 함은 컨트롤을 만드는 것이다. 즉 컨트롤+컨트롤=컨트롤 이렇게 만들기 위해, 먼저 UserControl을 생성 할 필요가 있다. View 폴더에 추가를 선택하여, SenderView라는 이름의 UserControl을 추가합니다. 그러면 XAML파일로 추가 됩니다. (XAML파일은 blend에서 편집이 가능합니다.)
<UserControl x:Class="Mvvm_Light.View.SenderView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:Command="http://www.galasoft.ch/mvvmlight"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding Source={StaticResource Locator}, Path=SenderViewModel}">
<Grid>
<Label Content="Sender" Margin="90,34,0,232"/>
<TextBox HorizontalAlignment="Left" Width="120" Height="20" Margin="50,266,0,11" Text="{Binding TextBoxText}" Background="#FFDE8E8E"/>
<Button Content="Send" Width="50" Height="25" Margin="183,265,67,10">
<Button.Background>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFF3F3F3" Offset="0"/>
<GradientStop Color="#FFEBEBEB" Offset="0.328"/>
<GradientStop Color="#FFDDDDDD" Offset="0.237"/>
<GradientStop Color="#FF631C1C" Offset="1"/>
</LinearGradientBrush>
</Button.Background>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<Command:EventToCommand Command="{Binding OnClickCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</UserControl>
- 여기서 보면은 DataContext="{Binding Source={StaticResource Locator}, Path=SenderViewModel}"은 Locator을 통해 SenderViewModel과 연결 하는 것을 볼 수있습니다. 즉, UI만 가지고 있는 View와 이벤트를 가지고 있는 ViewModel과 연결 하는 것입니다.
4. 그럼 MainWindow에 우리가 만든 View을 배치 해보겠습니다.
<Window x:Class="Mvvm_Light.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:Mvvm_Light.View"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<view:SenderView Grid.Row="0" Grid.Column="1" Foreground="Black" Background="#FFBA33CF" />
<GridSplitter HorizontalAlignment="Left" Width="5" Height="320" Margin="245,0,0,-21"/>
</Grid>
</Window>
5. 인제 보내는 것은 끝났고 메세지를 받는 녀석을 만들겠습니다. 동일하게 ViewModel을 생성합니다. 이름은 ReceiverViewModel로 하겠습니다.
<UserControl x:Class="Mvvm_Light.View.ReceiverView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding Source={StaticResource Locator}, Path=ReceiverViewModel}">
<Grid>
<Label Content="Receiver" Margin="90,34,0,232"/>
<Label Content="{Binding ContentText}" FontSize="20" Margin="65,255,40,0"/>
</Grid>
</UserControl>
6. ViewModelLocator 에 ViewModel들을 바인딩합니다.
/*
In App.xaml:
<Application.Resources>
<vm:ViewModelLocatorTemplate xmlns:vm="clr-namespace:Mvvm_Light.ViewModel"
x:Key="Locator" />
</Application.Resources>
In the View:
DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
*/
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using Mvvm_Light.Model;
namespace Mvvm_Light.ViewModel
{
public class ViewModelLocator
{
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<SenderViewModel>();
SimpleIoc.Default.Register<ReceiverViewModel>();
}
public SenderViewModel SenderViewModel
{
get
{
return ServiceLocator.Current.GetInstance<SenderViewModel>();
}
}
public ReceiverViewModel ReceiverViewModel
{
get
{
return ServiceLocator.Current.GetInstance<ReceiverViewModel>();
}
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
}
7. 인제 View 컨트롤러를 생성합니다. 이름은 ReceiverView이고 폴더는 View폴더입니다.
<UserControl x:Class="Mvvm_Light.View.ReceiverView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding Source={StaticResource Locator}, Path=ReceiverViewModel}">
<Grid>
<Label Content="Receiver" Margin="90,34,0,232"/>
<Label Content="{Binding ContentText}" FontSize="20" Margin="65,255,40,0"/>
</Grid>
</UserControl>
8. MainWindow에 ReceiverView를 배치합니다.
<Window x:Class="Mvvm_Light.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:Mvvm_Light.View"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<view:ReceiverView Grid.Row="0" Grid.Column="0" />
<view:SenderView Grid.Row="0" Grid.Column="1" Foreground="Black" Background="#FFBA33CF" />
<GridSplitter HorizontalAlignment="Left" Width="5" Height="320" Margin="245,0,0,-21"/>
</Grid>
</Window>
9. 인제 빌드하시고, 실행하시면 됩니다. 위소스는 제가 짠것이 아니라 보고 따라한 소스 한국말로 적은 것입니다.
- 테스트 해보니 아주 잘 작동 하였으니 무난하게 잘 될것이라 생각됩니다.
- C#이 처음인지라 신기하고 재미 있네요.
'C#의 속삭임' 카테고리의 다른 글
[C#][WPF] 첫시작. (0) | 2014.04.23 |
---|---|
[C#][WPF]데이터 바인딩 (0) | 2014.04.22 |
[C#][패턴] MVVM (0) | 2014.04.16 |
[C#][AxWebBrowser] AxWebBrowser 컨트롤러 (0) | 2014.04.08 |
[C#][WebBrowser] WebBrowser 컨트롤러 (0) | 2014.04.04 |