有没有办法来检查WPF当前是否在devise模式下执行?

有谁知道一些可用的全局状态variables,以便我可以检查代码当前是否在devise模式下执行(例如在Blend或Visual Studio中)?

它看起来像这样:

//pseudo code: if (Application.Current.ExecutingStatus == ExecutingStatus.DesignMode) { ... } 

我需要的原因是:当我的应用程序在Expression Blend中以devise模式显示时,我希望ViewModel改为使用“Design Customer类”,其中包含模拟数据的devise人员可以在devise模式下查看的数据。

但是,当应用程序正在执行时,我当然希望ViewModel使用返回实际数据的真实Customer类。

目前我通过devise人员解决这个问题,在他开始工作之前,进入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); } } } 

我相信你正在寻找GetIsInDesignMode ,它采用了一个DependencyObject。

IE浏览器。

 // 'this' is your UI element DesignerProperties.GetIsInDesignMode(this); 

编辑:当使用Silverlight / WP7时,你应该使用IsInDesignTool因为在Visual Studio中,有时候GetIsInDesignMode会返回false:

 DesignerProperties.IsInDesignTool 

编辑:最后,为了完整性,WinRT / Metro / Windows Store应用程序中的等效function是DesignModeEnabled

 Windows.ApplicationModel.DesignMode.DesignModeEnabled 

你可以做这样的事情:

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

从任何地方工作。 我用它来阻止devise器中播放的数据绑定video。

当Visual Studio自动生成一些代码使用它

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

如果你为你的大型WPF / Silverlight / WP8 / WinRT应用程序广泛使用Caliburn.Micro ,你可以在你的视图模型中使用方便和通用的 caliburn Execute.InDesignMode静态属性(并且它在Blend中的工作方式与Visual Studio ):

 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" //}; } } 

在这个相关的答案中提到了 WPF中指定devise时数据的其他(也许更新的)方法。

本质上,您可以使用ViewModel的devise时实例指定devise时数据:

 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:”devise时标签都消​​失了,所以你只能得到你的运行时数据上下文,但是你select设置它。

编辑您可能还需要这些行(我不确定,但他们似乎相关):

 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" 

我只用Visual Studio 2013和.NET 4.5testing过,但是这个技巧。

 public static bool IsDesignerContext() { var maybeExpressionUseLayoutRounding = Application.Current.Resources["ExpressionUseLayoutRounding"] as bool?; return maybeExpressionUseLayoutRounding ?? false; } 

虽然Visual Studio中的某些设置可能会将此值更改为false,但如果发生这种情况,我们可能只会检查此资源名是否存在。 当我在devise器外部运行我的代码时,它是null的。

这种方法的好处是,它不需要明确知道具体的App类,它可以在整个代码中使用。 特别是用虚拟数据填充视图模型。

我有一个想法,如果你的类不需要一个空的构造函数。

这个想法是创build一个空的构造函数,然后用ObsoleteAttribute标记它。 devise者忽略了过时的属性,但是如果你尝试使用它,编译器会产生一个错误,所以没有意外的使用它的风险。

(请原谅我的视觉基础 )

 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> 

上述代码的结果

如果你确实需要其他的空构造函数,这将不起作用。