web-dev-qa-db-ja.com

WPFが現在デザインモードで実行されているかどうかを確認する方法はありますか?

コードが現在デザインモード(たとえば、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);
        }
    }
}
136
Edward Tanguay

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
214
Richard Szalay

次のようなことができます:

DesignerProperties.GetIsInDesignMode(new DependencyObject());
107
Sacha Bruttin
public static bool InDesignMode()
{
    return !(Application.Current is App);
}

どこからでも動作します。これを使用して、データバインドされたビデオがデザイナーで再生されないようにします。

23
Patrick

Visual Studioが私のためにいくつかのコードを自動生成したとき、それは使用しました

if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) 
{
    ...
}
9
Darren

この関連する回答で述べられている のように、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" 
8
cod3monk3y

そして、大規模な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"
        //};
    }
}
7
Sevenate

受け入れられた答えは私にとってはうまくいきませんでした(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");
        }
    }
2
Ger Hobbelt

これは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クラスの明示的な知識を必要とせず、コード全体でグローバルに使用できることです。具体的には、ビューモデルにダミーデータを入力します。

2
John Leidegren

クラスが空のコンストラクタを必要としない場合、私はあなたのためのアイデアを持っています。

空のコンストラクターを作成し、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>

result of the above code

これは、実際に他の何かのために空のコンストラクタが必要な場合には機能しません。

1
DonkeyMaster