2010-05-20 4 views
6

mvvm 패턴의 wpf 사용자 컨트롤을 만들고 있습니다. 우리는 view (코드 숨김 파일에 코드 없음), viewmodel, model, dataaccess 파일을 가지고 있습니다.MVVM 패턴에서 wpf usercontrol을로드하는 방법

은 내가 MainWindowModel .cs과 결합 할 필요가 뷰 파일로 MainWindow를 .xaml을 보유하고 있습니다.

일반적으로 wpf 응용 프로그램에서는 App.xaml 파일의 onStartUp 이벤트를 사용하여이 작업을 수행 할 수 있습니다. 그러나 사용자 컨트롤에서 우리는 App.xaml을 가지고 있지 않기 때문에 ... 어떻게 구현합니까?

도와주세요 : (... 감사합니다 사전에!

답변

16

당신은 뷰 모델에)를 UserControl (보기를 결합하는 DataTemplate과 더불어, ContentControl를 사용할 수 있습니다

<DataTemplate DataType="{x:Type vm:MyViewModel}"> 
    <v:MyUserControl /> 
</DataTemplate> 

... 

<ContentControl Content="{Binding Current}" /> 

WPF를 것 DataTemplate을 자동으로 선택하십시오. Content

+0

콘텐츠 태그에 속성 (종속성 속성 또는 일반 속성)이 필요하지 않습니까? 아니면 ... "현재"가 동일한 내용을 어떻게 충족합니까? – Relativity

+0

안녕하세요 토마스, 위 쿼리에 대한 아이디어를 제공해 주시겠습니까? – Relativity

+1

위의 코드에서 'Current'는 데이터 컨텍스트의 유형 인 MyViewModel의 속성이됩니다 –

2

저는 MVVM Light Toolkit을 사용하고 있습니다.이 유형은 ViewModelLocator 클래스를 사용하여 prop 의 viewmodels에 erties 당신은 다음과 같이 당신의 Mainwindow.xaml에 ViewModelLocator에 대한 참조를 만듭니다. 격자 패널에서

<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True"/> 

, 또는 당신이, 당신은 다음과 같이 데이터 컨텍스트를 설정할 수 있습니다 사용하고 어떤 :

<Grid DataContext="{Binding MainWindowViewModel, Source={StaticResource Locator}}"> 
... 
</Grid> 

또한 잠재적으로보기에 다른 뷰 모델 구현을 교환 할 수 있다는 점에서 좀 더 유연성을 추가 MEFedMVVM로 갈 수있다.

이러한 라이브러리의 유연성은 ViewModelLocator 및 MEFedMVVM이 어떤 클래스와도 함께 작동 할 수 있기를 바라지 않는 경우 ViewModel 기본 클래스를 사용할 필요가 없다는 것입니다.

2

두 가지 범주 중 하나 인 "보기 첫 번째"또는 "먼저 모델"로 끝나는 무한한 방법이 있습니다.

private void WindowLoaded(object sender, EventArgs args) 
{ 
    this.DataContext = ViewModelService.GetViewModelX(); 
} 

에서 :는 "첫 번째보기"모드에서

보기를 (예를 들어, 당신의 MainWindow를)

는보기 뷰 모델을 인스턴스화하고)의 데이터 컨텍스트로 설정합니다 (코드 숨김에서 예) 먼저 및 생성 "모델 첫 번째"모드는 ViewModel이 먼저 있고 그 다음에 뷰를 인스턴스화합니다.

// method of the viewmodel 
public void LoadView() 
{ 
    // in this example the view abstracted using an interface 
    this.View = ViewService.GetViewX(); 
    this.View.SetDataContext(this); 
    this.View.Show();  
} 

여기에 제시된 예는 많은 경우의 한 가지 방법 일뿐입니다. 다양한 MVVM frameworks을보고 어떻게하는지 볼 수 있습니다.

+0

감사합니다. 그것에 대해 살펴 보겠습니다. – Relativity

+0

답변을 원하는 대답으로 자유롭게 표시 할 수 있습니다. – bitbonk

+0

MVVM 모델에서 뷰의 파일 뒤에 코드로 코드를 넣을 수 있습니까? – Relativity

0

우리는 객체 ..as 내부 메소드를 호출 ObjectDataProvider를 사용할 수는 다음과 같습니다

<ObjectDataProvider ObjectType="{x:Type local:TemperatureScale}" 
        MethodName="ConvertTemp" 
        x:Key="convertTemp"> 

나는이 오래된 알고 질문에 대답 DataTemplate을

5

사용하여 동일한 기능을 수행 할 어쨌든 거기, 그러나 나는 다른 접근법을 가지고있다. 나는 앱에서 암묵적인 관계를 만들고 싶다.xaml 파일 :

<Application.Resources> 
    <DataTemplate DataType="{x:Type ViewModels:KioskViewModel}"> 
     <Views:KioskView /> 
    </DataTemplate> 
</Application.Resources> 

이렇게하면 아무 데나 DataContext를 설정할 필요가 없습니다.

UPDATE >>>

Natraj의 요청을 @Vignesh에 대한 응답으로

, 여기 풀러 설명입니다

당신이 Resources 요소에 DataTemplate을 설정 한 후에

,이 예에서 KioskView를 표시 할 수는 KioskViewModel의 인스턴스를 XAML의 모든 위치에 추가합니다. 이것은 MainWindow을 채울 수도 있고 화면의 특정 섹션 안에있을 수도 있습니다. ListBoxKioskViewModel의 여러 인스턴스를 호스팅 할 수도 있으며 복수 KioskView 인스턴스를 생성합니다.

요구 사항에 따라 두 가지 방법으로 KioskViewModel의 인스턴스를 XAML에 추가 할 수 있습니다. 한 가지 방법은 KioskViewModel.cs 파일이 포함 된 프로젝트의 XML 네임 스페이스를 선언하고보기를 표시 할 페이지에 ContentControl의 인스턴스를 추가하기 만하면됩니다.

<UserControl x:Class="Kiosk.Views.MainView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ViewModels="clr-namespace:Kiosk.ViewModels"> 
    <UserControl.Resources> 
     <ViewModels:KioskViewModel x:Key="KioskViewModel" /> 
     <DataTemplate DataType="{x:Type ViewModels:KioskViewModel}"> 
      <Views:KioskView /> 
     </DataTemplate> 
    </UserControl.Resources> 
    <ContentControl Content="{StaticResource KioskViewModel}" /> 
</UserControl> 

내가 WPF와 MVVM 디자인 패턴을 사용하는 것을 선호, 그래서 나는 것 : 당신이 있다면 예를 들어, UserControlMainView라고하고 KioskViewModel.cs 파일이 Kiosk.ViewModels 네임 스페이스에 있었다,이 같은 기본 XAML을 사용할 수 있습니다 필수 INotifyPropertyChanged 인터페이스를 구현하는 것과 같은 유용한 기능을 제공하는 기본보기 모델 클래스. 그런 다음 유형의 기본 (최상위)보기 모델에 ViewModel이라는 속성이 있습니다. 이를 통해 ViewModel 속성을 BaseViewModel에서 파생 된 모든 뷰 모델로 변경하고 뷰 모델에서 연결된 뷰를 변경할 수있는 좋은 방법을 제공합니다.

예를 들어, MainView에 바인딩 된 MainViewModel.cs 클래스의 필드와 관련된 특성이있다 :

private BaseViewModel viewModel = new KioskViewModel(); 
public BaseViewModel ViewModel 
{ 
    get { return viewModel; } 
    set { viewModel = value; NotifyPropertyChanged("ViewModel"); } 
} 

당신이 볼 수 있듯이, 그것은이 KioskViewModel 인스턴스로 시작합니다, 그러나 어떤 변경할 수 있습니다 사용자 상호 작용에 대한 응답으로 언제든지 다른보기. 이 설정의 경우, XAML은 매우 유사하지만, 대신 Resources 요소의 뷰 모델의 인스턴스를 선언, 우리는 MainViewModel에서 속성에 바인딩이 예를 들어, 우리가 필요로하는 것을

<UserControl x:Class="Kiosk.Views.MainView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ViewModels="clr-namespace:Kiosk.ViewModels"> 
    <ContentControl Content="{Binding ViewModel}" /> 
</UserControl> 

<Application.Resources> 
    <DataTemplate DataType="{x:Type ViewModels:MainViewModel}"> 
     <Views:MainView /> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type ViewModels:KioskViewModel}"> 
     <Views:KioskView /> 
    </DataTemplate> 
</Application.Resources> 
+0

이 방법에 대해 설명해 주시겠습니까? 시도했지만 아무 것도 내보기에 묶이지 않습니다. 나는 오래되었지만 감사합니다. –

0

당신은 아마 MSDN 볼 수 있습니다 다음 App.xaml 파일 DataTemplate의 (유용한이 방법을 만들기 위해 또는 그 이상)의 두 가지를 선언합니다. 좋은 리소스라고 생각하지만, usercontrols를 사용하는 방법을 설명하지는 않지만, 길을 찾을 수 있습니다.