是否有人知道某些可用的全局状态变量,以便我可以检查代码当前是否在设计模式下执行(例如在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);
}
}
}
答案 0 :(得分:209)
我相信你正在寻找GetIsInDesignMode,它需要一个DependencyObject。
即
// 'this' is your UI element
DesignerProperties.GetIsInDesignMode(this);
编辑:使用Silverlight / WP7时,您应该使用IsInDesignTool
,因为GetIsInDesignMode
有时在Visual Studio中会返回false:
DesignerProperties.IsInDesignTool
编辑最后,为了完整起见,WinRT / Metro / Windows应用商店应用中的等价物为DesignModeEnabled
:
Windows.ApplicationModel.DesignMode.DesignModeEnabled
答案 1 :(得分:106)
您可以这样做:
DesignerProperties.GetIsInDesignMode(new DependencyObject());
答案 2 :(得分:23)
public static bool InDesignMode()
{
return !(Application.Current is App);
}
随处工作。我用它来阻止数据绑定视频在设计师中播放。
答案 3 :(得分:9)
当Visual Studio自动为我生成一些代码时,它使用了
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
...
}
答案 4 :(得分:8)
还有其他(可能更新)的方法在WPF中指定设计时数据,mentioned in this related answer。
基本上,您可以使用design-time instance of your ViewModel:
指定设计时数据d:DataContext="{d:DesignInstance Type=v:MySampleData, IsDesignTimeCreatable=True}"
或specifying sample data in a XAML file:
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="...">
在运行时,所有的&#34; d:&#34;设计时标签消失,因此您只能获得运行时数据上下文,但是您选择设置它。
修改强> 您可能还需要这些行(我不确定,但它们似乎相关):
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
答案 5 :(得分:7)
如果您在大型 WPF / Silverlight / WP8 / WinRT 应用程序中广泛使用Caliburn.Micro,则可以使用方便且通用校准的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"
//};
}
}
答案 6 :(得分:2)
我只使用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
类,并且可以在整个代码中全局使用。特别是用虚拟数据填充视图模型。
答案 7 :(得分:2)
接受的答案对我不起作用(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");
}
}
答案 8 :(得分:1)
如果你的班级不需要空的构造函数,我有一个想法。
想法是创建一个空构造函数,然后使用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>
如果确实需要空构造函数来处理其他内容,这将无效。