DataContext 속성을 사용하여 XAML의 창에서 ViewModel을 설정하려면 어떻게해야합니까?


96

질문은 거의 모든 것을 말해줍니다.

나는 창이 있고 ViewModel에 전체 네임 스페이스를 사용하여 DataContext를 설정하려고 시도했지만 뭔가 잘못된 것 같습니다.

<Window x:Class="BuildAssistantUI.BuildAssistantWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="BuildAssistantUI.ViewModels.MainViewModel">

Mike Nakis에 이어 저는 ViewModel을 수동으로 생성하고 그 안에있는 이벤트를 구독하려고했지만 프레임 워크가 또 다른 ViewModel을 생성하고 있다는 것을 알았습니다. 따라서 내가 구독 한 viewModel은 뷰에 연결된 것이 아닙니다.
jlady

이 자신을 뷰 모델을 인스턴스화하는 외에, 당신이되었다는 것을 의미합니까 또한 다른 방법으로 뷰 모델의 유형을 지정? 생성자 매개 변수가 필요한 뷰 모델의 두 번째 이점은 프레임 워크가 인스턴스화 할 수 없거나 해당 매개 변수에 대한 기본값을 전달해야한다는 것입니다.이 경우 프레임 워크에서 인스턴스화를 쉽게 감지 할 수 있습니다.
Mike Nakis

XAML 디자이너도 뷰 모델을 인스턴스화 할 수 있어야 할 수도 있지만이 디자이너는 나에게 유용하지 않았기 때문에 (문제를 일으킬뿐) 사용하지 않기 때문에 개인적으로 그 사용 사례에 대해 신경 쓰지 않습니다.
Mike Nakis

답변:


113

다른 사람들이 제공 한 솔루션 (좋고 올바른) 외에도 XAML에서 ViewModel을 지정하면서도 특정 ViewModel을 View에서 분리하는 방법이 있습니다. 분리 된 테스트 케이스를 작성하고자 할 때 유용합니다.

App.xaml에서 :

<Application
    x:Class="BuildAssistantUI.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:BuildAssistantUI.ViewModels"
    StartupUri="MainWindow.xaml"
    >
    <Application.Resources>
        <local:MainViewModel x:Key="MainViewModel" />
    </Application.Resources>
</Application>

MainWindow.xaml에서 :

<Window x:Class="BuildAssistantUI.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="{StaticResource MainViewModel}"
    />

오 와우 ... 고마워요. 이미 답변으로 표시했지만 추가해 주셔서 감사합니다. 그것을 사용할 것입니다.
Nicholas 2011 년

@Nicholas : 나는 당신의 결정에 동의 그래서 다른 대답은, 질문에 대한 완벽한
Merlyn 모건 - 그레이엄

8
이 방법은 MainWindow의 모든 인스턴스에 대해 동일한 ViewModel 인스턴스를 사용한다는 점에 유의하십시오. 이 경우에서 알 수 있듯이 창이 단일 인스턴스이면 괜찮지 만 MDI 또는 탭 응용 프로그램의 경우와 같이 창의 여러 인스턴스를 표시하는 경우에는 그렇지 않습니다.
조쉬

1
실제로 Josh의 대답은 DataContext에서 형식 안전성을 제공하므로 더 좋습니다. 따라서 일부 속성 이름 / 경로를 입력 할 필요없이 DataContext에 직접 바인딩 할 수 있습니다.
Josh M.

149

대신 이것을 시도하십시오.

<Window x:Class="BuildAssistantUI.BuildAssistantWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:VM="clr-namespace:BuildAssistantUI.ViewModels">
    <Window.DataContext>
        <VM:MainViewModel />
    </Window.DataContext>
</Window>

3
이 옵션이 가장 좋습니다. VM이 MainWindow에만 사용되는 경우 더 깨끗해 보입니다.
Andrew Grothe 2013 년

13
Window요소 의 속성을 사용하여 데이터 컨텍스트를 설정하는 방법이 DataContext="VM:MainWindowViewModel"있습니까?
올리버

이것이 올바른 방법입니다!
JavierIEH 2015

나는 왜 한 쪽이 다른 쪽보다 나은지 완전히 이해하지 못합니다. 또한 일부 사람들이 "동적 자원"을 사용하는 방식과 비교하여 이러한 방식의 차이를 완전히 보지 못합니다. 이게 뭐야?
Travis Tubbs

1
@Oliver를 구현 MarkupExtension해야하고 VM에서 수행 한 적이 없지만 변환기를 사용하여 변환기 인스턴스가 하나만 있는지 확인 하고 변환기 네임 스페이스의 지점을 ="{converters:SomethingConverter}"암시하는 xaml에서 직접 호출 할 수 xmlns:converters있습니다. public abstract class BaseValueConverter<T> : MarkupExtension, IValueConverter where T : class, new() { private static T _converter; public override object ProvideValue(IServiceProvider serviceProvider) { return _converter ?? (_converter = new T()); } }
Whazz

11

MainViewModel을 인스턴스화하고 데이터 컨텍스트로 설정해야합니다. 귀하의 진술에서 그것은 단지 그것을 문자열 값으로 간주합니다.

     <Window x:Class="BuildAssistantUI.BuildAssistantWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BuildAssistantUI.ViewModels">
      <Window.DataContext>
        <local:MainViewModel/>
      </Window.DataContext>

고마워요.
Nicholas 2011 년

3

Catel 을 사용해 볼 수도 있습니다 . (Window 대신) DataWindow 클래스를 정의 할 수 있으며 해당 클래스는 자동으로 뷰 모델을 생성합니다. 이렇게하면 원래 게시물에서했던 것처럼 ViewModel의 선언을 사용할 수 있으며 뷰 모델은 여전히 ​​생성되고 DataContext로 설정됩니다.

예제는 이 기사 를 참조하십시오 .


2

viewmodel을 지정하는 다음과 같은 방법도 있습니다.

using Wpf = System.Windows;

public partial class App : Wpf.Application //your skeleton app already has this.
{
    protected override void OnStartup( Wpf.StartupEventArgs e ) //you need to add this.
    {
        base.OnStartup( e );
        MainWindow = new MainView();
        MainWindow.DataContext = new MainViewModel( e.Args );
        MainWindow.Show();
    }
}

<랜트>

이전에 제안 된 모든 솔루션에는 MainViewModel매개 변수없는 생성자 가 있어야합니다.

Microsoft는 매개 변수없는 생성자를 사용하여 시스템을 구축 할 수 있다는 인상을 받았습니다. 당신도 그 인상을 받고 있다면 다른 해결책을 사용하십시오.

생성자에 매개 변수가 있어야하므로 객체의 인스턴스화는 매직 프레임 워크의 손에 맡길 수 없다는 것을 알고있는 사람들에게 뷰 모델을 지정하는 올바른 방법은 위에서 보여준 방법입니다.

</ Rant>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.