はじめに
みなさんVisual StudioのXAMLデザイナーを使って画面の構築を行っていますか?
Blendを使うというゴリゴリの方もいらっしゃると思いますが、実行して確認しながら調整を繰り返している方も多いと思います。
Blendの操作覚えるのも面倒ですしXAMLデザイナーは、動的なデータを利用した画面を作成すると途端にエラーになったり崩れたりします。
XAMLデザイナーでエラーになってもアプリケーションの実行には支障がない事を知ってしまうとXAMLデザイナー自体を信用しなくなってしまう人も多いでしょう。
ですが、実行と確認を繰り返すのは、効率的な開発フローとは言えません。
ギリギリまで、XAMLデザイナー上で画面を確認しながら実装するのが、最も効率的です。(まあ、みなさんそう思ってると思いますが)
XAMLデザイナーを活用する鍵は、XAMLデザイナー専用のデータを用意することです。
XAMLデザイナー専用のViewModel
ViewModelは、アプリケーション実行時に、動的データをViewへ提供する訳ですが、当然ながら実行前ですからデータは用意できません。
本番用のViewModelをそのままDataContextへ設定していると最悪例外が発生して、デザイナーがエラー表示になってしまいます。
ちょっと面倒ですが、XAMLデザイナー専用のViewModelを作成して、ダミーデータをViewへ渡してやることで、安心して画面を構築できます。
下のソースのように、タグを使用して、デザイナー専用のViewModelを設定します。
<Window x:Class="Sample.Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Zephyros.Framework.Demo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:Sample.Demo.ViewModels"
Title="MainWindow"
Width="525"
Height="350"
mc:Ignorable="d">
<d:DesignProperties.DataContext>
<vm:MainWindowDesignViewModel />
</d:DesignProperties.DataContext>
<Grid />
</Window>
デザイナー実行時なのか判定する
XAMLデザイナーは、コードをある程度実行した結果を表示します。
そのため実行時でないとエラーになってしまうコードが、ViewModelに記述されていると例外が発生して正しく画面をプレビューできないわけです。
それなら実行時に、デザイナーが実行しているのかを判定すれば、エラーになるのを回避できますよね。
もちろん.Netでは、判定機能が用意されています。
public class MainWindowViewModel : ViewModel
{
public MainWindowViewModel()
{
if(this.IsInDesignMode())
{
// テストデータを設定
}
}
public bool IsInDesignMode()
{
bool result = true;
var window = System.Windows.Application.Current.MainWindow;
if (window != null)
{
if (!IsInDesignMode(window))
{
result = false;
}
}
return result;
}
public bool IsInDesignMode(System.Windows.DependencyObject element)
{
return System.ComponentModel.DesignerProperties.GetIsInDesignMode(element);
}
}