DataContextプロパティを使用してXAMLのウィンドウにViewModelを設定するにはどうすればよいですか?


96

質問はほとんどすべてを言います。

ウィンドウがあり、完全な名前空間を使用してDataContextをViewModelに設定しようとしましたが、何か間違っているようです。

<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">

回答:


112

他の人々が提供したソリューション(優れた正しい)に加えて、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}"
    />

わあ...ありがとう。私はすでにこれを回答済みとしてマークしましたが、あなたの追加は大歓迎です。それを使用します。
ニコラス

@ニコラス:他の答えは質問に最適です。そのため、私はあなたの決定に同意します
メルリンモーガングラハム

8
このアプローチでは、MainWindowのすべてのインスタンスに同じViewModelインスタンスを使用することに注意してください。このケースが意味するようにウィンドウが単一インスタンスである場合は問題ありませんが、MDIまたはタブ付きアプリケーションの場合など、ウィンドウの複数のインスタンスを表示している場合はそうではありません。
Josh

1
実際、ジョシュの答えは、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 2017年

1
@Oliverあなたは実装する必要がありMarkupExtensionますが、VMでは決して実行しませんが、コンバーターでこれを実行して、コンバーターのインスタンスが1つだけ存在することを確認し="{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()); } }
ファズ

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>

ありがとう、私はそれがそうしていると思った。
ニコラス

3

Catelを試してみてください。これにより、(ウィンドウの代わりに)データウィンドウクラスを定義でき、そのクラスによってビューモデルが自動的に作成されます。このようにして、元の投稿と同じようにViewModelの宣言を使用できます。ビューモデルは引き続き作成され、DataContextとして設定されます。

については、この記事を参照してください。


1

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は、パラメーターなしのコンストラクターが必要です。

マイクロソフトは、パラメーターなしのコンストラクターを使用してシステムを構築できるという印象を受けています。あなたもその印象の下にある場合は、先に進んで他のソリューションのいくつかを使用してください。

コンストラクターはパラメーターを持つ必要があるため、オブジェクトのインスタンス化をマジックフレームワークに任せることはできないことを知っている人にとっては、上で示したビューモデルの適切な方法を指定する方法です。

</ Rant>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.