왜 이래?
MainWindow.xaml :
<Window x:Class="MVVMProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ContentControl Content="{Binding}"/>
</Grid>
</Window>
ExampleView.xaml을 다음과 같이 설정하십시오.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vms="clr-namespace:MVVMProject.ViewModels">
<DataTemplate DataType="{x:Type vms:ExampleVM}" >
<Grid>
<ActualContent/>
</Grid>
</DataTemplate>
</ResourceDictionary>
그리고 다음과 같이 창을 만듭니다.
public partial class App : Application {
protected override void OnStartup(StartupEventArgs e) {
base.OnStartup(e);
MainWindow app = new MainWindow();
ExampleVM context = new ExampleVM();
app.DataContext = context;
app.Show();
}
}
언제 이렇게 할 수 있을까요?
App.xaml : (시작 창 /보기 설정)
<Application x:Class="MVVMProject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="ExampleView.xaml">
</Application>
ExampleView.xaml : (ResourceDictionary가 아닌 창)
<Window x:Class="MVVMProject.ExampleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vms="clr-namespace:MVVMProject.ViewModels">
>
<Window.DataContext>
<vms:ExampleVM />
</Window.DataContext>
<Grid>
<ActualContent/>
</Grid>
</Window>
기본적으로 “View as DataTemplate”(VaD) 대 “View as Window”(VaW)입니다.
비교에 대한 나의 이해는 다음과 같습니다.
- VaD : 창을 닫지 않고 뷰를 전환 할 수 있습니다. (이것은 내 프로젝트에 바람직하지 않습니다)
- VaD : VM은 뷰에 대해 전혀 알지 못하지만 VaW에서는 다른 창을 열 때만 인스턴스화 할 수 있어야합니다.
- VaW : 실제로 디자이너에서 xaml이 렌더링되는 것을 볼 수 있습니다 (적어도 현재 설정에서는 VaD를 사용할 수 없습니다).
- VaW : 창을 열고 닫을 때 직관적으로 작동합니다. 각 창에는 해당 View (및 ViewModel)가 있습니다.
- VaD : ViewModel은 속성을 통해 초기 창 너비, 높이, 크기 조정 가능성 등을 전달할 수 있습니다 (VaW에서는 창에서 직접 설정 됨).
- VaW : FocusManager.FocusedElement를 설정할 수 있습니다 (VaD에서 방법이 확실하지 않음).
- VaW : 내 창 유형 (예 : 리본, 대화 상자)이 뷰에 통합되므로 파일이 적습니다.
그래서 여기서 무슨 일이 일어나고 있습니까? XAML로 창을 빌드하고 VM의 속성을 통해 데이터에 깔끔하게 액세스 한 다음 작업을 수행 할 수는 없나요? 코드 숨김은 동일합니다 (거의 없음).
모든 View 항목을 ResourceDictionary로 섞어 야하는 이유를 이해하는 데 어려움을 겪고 있습니다.
답변
사람들 DataTemplates
은 ViewModel에 따라 뷰를 동적으로 전환하고자 할 때 이러한 방식을 사용 합니다.
<Window>
<Window.Resources>
<DataTemplate DataType="{x:Type local:VM1}">
<!-- View 1 Here -->
</DataTemplate>
<DataTemplate DataType="{x:Type local:VM2}">
<!-- View 2 here -->
</DataTemplate>
</Window.Resources>
<ContentPresenter Content="{Binding}"/>
</Window>
그래서,
경우는 Window.DataContext
의 인스턴스 VM1
, 다음 View1
, 표시됩니다
그리고 만약
Window.DataContext
의 인스턴스 인 VM2
다음, View2
표시됩니다.
물론,보기가 1 개만 예상되고 변경되지 않으면 전혀 의미가 없습니다.
답변
VaD에서 뷰 모델은 뷰에 대해 아무것도 모르기 때문에 뷰 모델 만 있고 뷰가없는 완전히 작동하는 애플리케이션을 구축 할 수 있습니다. 이로 인해 전적으로 코드로 구동 할 수있는 애플리케이션을 작성할 수 있습니다. 이는 GUI없이 통합 테스트를 수행 할 수있는 가능성으로 이어집니다. GUI를 통한 통합 테스트는 취약한 것으로 악명이 높지만 뷰 모델을 통한 테스트는 더 강력해야합니다.
답변
내 개인적인 경험으로 볼 때 : 두 작업 모델은 사용자가 원하는 것과 응용 프로그램 요구 사항에 따라 사용할 수 있습니다. 뒤에있는 아이디어 VaD
는 콘텐츠와 컨테이너를 디 카플링하는 것입니다. 구현 VaD
하는 경우이 유형의 항목을 표시 할 때마다 기본적으로이 템플릿을 사용할 수 있습니다. ItemsControls
(목록, 목록보기, 그리드 등) 및 ContentControls
바인딩을 만드는 데만 사용할 수 있습니다 . 당신이 말했듯이, VaD
새 창을 닫고 열지 않고 창 내용을 전환하는 작업입니다. 또한를 사용하여 뷰를 정의한 UserControls
다음 포커스가있는 요소를 제어 할 수 있으며 코드 뒤에서 코드를 관리 할 수도 있습니다. 따라서 데이터 템플릿은 다음과 같을 수 있습니다.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vms="clr-namespace:MVVMProject.ViewModels">
<DataTemplate DataType="{x:Type vms:ExampleVM}" >
<CustomUserControl A="{Binding A}" B="{Binding B}" DataContext="{Binding}" .../>
</DataTemplate>
또한 UserControl
바인딩을 허용하고 앱을 분리하기 때문에 종속성 속성을 설정할 수도 있습니다.
물론 앱에 동적 콘텐츠 전환이 필요하지 않은 경우 VaW
기본 창이나 다른 창에 사용하는 것이 좋습니다. 실제로 VaW
및 VaD
. 이 마지막 항목은 창을 필요로하지 않는 앱의 내부 항목에 사용할 수 있습니다. 애플리케이션 요구 사항과 앱 개발에 소요되는 시간에 따라 더 나은 것을 선택합니다. 이 개인적인 경험이 도움이되기를 바랍니다.