【WPF(MVVM)】DataContextを毎回書かずにViewModelを自動で関連付ける方法

未分類

シンプルなMVVMではViewごとにDataContextを設定することが多いと思うんだけど、
xxxxViewなら同じ名前のxxxxViewModelを探しにいって関連付けをしてくれる処理を書いたよ

※命名規則(xxxxView ↔ xxxxViewModel)が守られていることが前提

関連付けの処理

ViewModelLocator.cs(View → ViewModelへ名前変換)

汎用系・便利系のクラスとかメソッドとか突っ込んでるcommonフォルダに
ViewModelLocator.csを作る

このクラスがxxxxViewModelを探しに行く

using System;

namespace XXXXXXXXX.Common
{
    public static class ViewModelLocator
    {
        public static object Resolve(object view)
        {
            var viewType = view.GetType();

            var fullName = viewType.FullName
                ?? throw new InvalidOperationException("Viewの型名が取得できません");

            var viewModelName = fullName.EndsWith("View") ? fullName.Replace("View", "ViewModel") 
                : fullName.Concat("ViewModel").ToString() ?? string.Empty;

            var vmType = Type.GetType(viewModelName)
                ?? throw new InvalidOperationException($"ViewModelが見つかりません: {viewModelName}");

            // 今回は引数なしのViewModelを想定したシンプルな実装
            return Activator.CreateInstance(vmType)
                ?? throw new InvalidOperationException($"ViewModelのインスタンス生成に失敗しました: {vmType.Name}");
        }
    }
}

xxxxView.xaml.cs

さっきのメソッドをコンストラクタで呼んで
画面を開くタイミングで関連付けをする

if (DataContext == null)
{
    // ViewModelのインスタンスを作成
    DataContext = ViewModelLocator.Resolve(this);
}

自分の場合は、
Viewに必ず継承させる基底クラスを作成していて、そこに書いてるよ

タイトルとURLをコピーしました