コードが現在デザインモード(たとえば、BlendまたはVisual Studio)で実行されているかどうかを確認できるように、利用可能なグローバル状態変数を知っていますか?
次のようになります。
//pseudo code:
if (Application.Current.ExecutingStatus == ExecutingStatus.DesignMode)
{
...
}
これが必要な理由は、Expression Blendでデザインモードでアプリケーションを表示するときに、ViewModelで、デザイナーがデザインモードで表示できるモックデータを含む「Design Customerクラス」を代わりに使用することです。
ただし、アプリケーションが実際に実行されているときは、もちろん、ViewModelで実際のデータを返す実際のCustomerクラスを使用する必要があります。
現在、私はデザイナーが作業する前にViewModelに移動し、「ApplicationDevelopmentMode.Executing」を「ApplicationDevelopmentMode.Designing」に変更することでこれを解決しています。
public CustomersViewModel()
{
_currentApplicationDevelopmentMode = ApplicationDevelopmentMode.Designing;
}
public ObservableCollection<Customer> GetAll
{
get
{
try
{
if (_currentApplicationDevelopmentMode == ApplicationDevelopmentMode.Developing)
{
return Customer.GetAll;
}
else
{
return CustomerDesign.GetAll;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
DependencyObjectを受け取る GetIsInDesignMode を探していると思います。
すなわち。
// 'this' is your UI element
DesignerProperties.GetIsInDesignMode(this);
編集:Silverlight/WP7を使用する場合は、IsInDesignTool
が可能なため GetIsInDesignMode
を使用する必要があります。 Visual Studioで時々falseを返します:
DesignerProperties.IsInDesignTool
Edit:そして最後に、完全性のために、WinRT/Metro/Windows Storeアプリケーションで同等のものは DesignModeEnabled
:
Windows.ApplicationModel.DesignMode.DesignModeEnabled
次のようなことができます:
DesignerProperties.GetIsInDesignMode(new DependencyObject());
public static bool InDesignMode()
{
return !(Application.Current is App);
}
どこからでも動作します。これを使用して、データバインドされたビデオがデザイナーで再生されないようにします。
Visual Studioが私のためにいくつかのコードを自動生成したとき、それは使用しました
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
...
}
この関連する回答で述べられている のように、WPFでデザイン時データを指定する他の(おそらく新しい)方法があります。
基本的に、 ViewModelの設計時インスタンス を使用して設計時データを指定できます。
d:DataContext="{d:DesignInstance Type=v:MySampleData, IsDesignTimeCreatable=True}"
または XAMLファイルでサンプルデータを指定 :
d:DataContext="{d:DesignData Source=../DesignData/SamplePage.xaml}">
SamplePage.xaml
ファイルプロパティを次のように設定する必要があります。
BuildAction: DesignData
Copy to Output Directory: Do not copy
Custom Tool: [DELETE ANYTHING HERE SO THE FIELD IS EMPTY]
これらをUserControl
タグに次のように配置します。
<UserControl
...
xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
...
d:DesignWidth="640" d:DesignHeight="480"
d:DataContext="...">
実行時には、すべての「d:」デザインタイムタグが消えるため、実行時のデータコンテキストのみを取得しますが、設定を選択します。
Editこれらの行も必要な場合があります(確かではありませんが、関連があるようです):
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
そして、大規模なWPF/Silverlight/WP8/WinRTアプリケーションに Caliburn.Micro を広範囲に使用する場合、便利なuniversalcaliburn's Execute.InDesignMode
ビューモデルの静的プロパティ(およびVisual Studioと同様にBlendでも機能します):
using Caliburn.Micro;
// ...
/// <summary>
/// Default view-model's ctor without parameters.
/// </summary>
public SomeViewModel()
{
if(Execute.InDesignMode)
{
//Add fake data for design-time only here:
//SomeStringItems = new List<string>
//{
// "Item 1",
// "Item 2",
// "Item 3"
//};
}
}
受け入れられた答えは私にとってはうまくいきませんでした(VS2019)。
何が起こっているのかを調べた後、私はこれを思いつきました:
public static bool IsRunningInVisualStudioDesigner
{
get
{
// Are we looking at this dialog in the Visual Studio Designer or Blend?
string appname = System.Reflection.Assembly.GetEntryAssembly().FullName;
return appname.Contains("XDesProc");
}
}
これはVisual Studio 2013と.NET 4.5でのみテストしましたが、うまくいきます。
public static bool IsDesignerContext()
{
var maybeExpressionUseLayoutRounding =
Application.Current.Resources["ExpressionUseLayoutRounding"] as bool?;
return maybeExpressionUseLayoutRounding ?? false;
}
ただし、Visual Studioの設定によってこの値がfalseに変更される可能性があります。それが発生した場合、このリソース名が存在するかどうかを確認するだけです。デザイナーの外でコードを実行したのはnull
でした。
このアプローチの利点は、特定のApp
クラスの明示的な知識を必要とせず、コード全体でグローバルに使用できることです。具体的には、ビューモデルにダミーデータを入力します。
クラスが空のコンストラクタを必要としない場合、私はあなたのためのアイデアを持っています。
空のコンストラクターを作成し、ObsoleteAttributeでマークするという考え方です。デザイナは廃止された属性を無視しますが、使用しようとするとコンパイラがエラーを発生させるため、誤って自分で使用するリスクはありません。
Public Class SomeClass
<Obsolete("Constructor intended for design mode only", True)>
Public Sub New()
DesignMode = True
If DesignMode Then
Name = "Paula is Brillant"
End If
End Sub
Public Property DesignMode As Boolean
Public Property Name As String = "FileNotFound"
End Class
そして、xaml:
<UserControl x:Class="TestDesignMode"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:AssemblyWithViewModels;Assembly=AssemblyWithViewModels"
mc:Ignorable="d"
>
<UserControl.Resources>
<vm:SomeClass x:Key="myDataContext" />
</UserControl.Resources>
<StackPanel>
<TextBlock d:DataContext="{StaticResource myDataContext}" Text="{Binding DesignMode}" Margin="20"/>
<TextBlock d:DataContext="{StaticResource myDataContext}" Text="{Binding Name}" Margin="20"/>
</StackPanel>
</UserControl>
これは、実際に他の何かのために空のコンストラクタが必要な場合には機能しません。