C# 有没有办法检查WPF当前是否在设计模式下执行?
是否有人知道一些可用的全局状态变量,以便我可以检查代码当前是否以设计模式(如Blend或Visual Studio)执行? 它看起来像这样:C# 有没有办法检查WPF当前是否在设计模式下执行?,c#,wpf,expression-blend,C#,Wpf,Expression Blend,是否有人知道一些可用的全局状态变量,以便我可以检查代码当前是否以设计模式(如Blend或Visual Studio)执行? 它看起来像这样: //pseudo code: if (Application.Current.ExecutingStatus == ExecutingStatus.DesignMode) { ... } DesignerProperties.GetIsInDesignMode(new DependencyObject()); <UserControl
//pseudo code:
if (Application.Current.ExecutingStatus == ExecutingStatus.DesignMode)
{
...
}
DesignerProperties.GetIsInDesignMode(new DependencyObject());
<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="...">
我需要这样做的原因是:当我的应用程序在Expression Blend的设计模式下显示时,我希望ViewModel使用一个“design Customer类”,该类中包含模拟数据,设计者可以在设计模式下查看这些数据
然而,当应用程序实际执行时,我当然希望ViewModel使用返回真实数据的realcustomer类
目前,我通过让设计师在处理它之前进入ViewModel并将“ApplicationDevelopmentMode.Executing”更改为“ApplicationDevelopmentMode.Design”来解决这个问题:
public CustomersViewModel()
{
_currentApplicationDevelopmentMode=ApplicationDevelopmentMode.设计;
}
公共可观测集合GetAll
{
得到
{
尝试
{
if(_currentApplicationDevelopmentMode==ApplicationDevelopmentMode.Developing)
{
return Customer.GetAll;
}
其他的
{
返回CustomerDesign.GetAll;
}
}
捕获(例外情况除外)
{
抛出新异常(例如消息);
}
}
}
您可以执行以下操作:
//pseudo code:
if (Application.Current.ExecutingStatus == ExecutingStatus.DesignMode)
{
...
}
DesignerProperties.GetIsInDesignMode(new DependencyObject());
<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="...">
我相信您正在寻找,它需要一个DependencyObject 即 编辑:在使用Silverlight/WP7时,您应该使用,因为在Visual Studio中,
GetIsInDesignMode
有时会返回false:
DesignerProperties.IsInDesignTool
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"
//};
}
}
编辑:最后,为了完整性起见,WinRT/Metro/Windows应用商店应用程序中的等效项是:
当VisualStudio为我自动生成一些代码时,它使用了
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
...
}
如果您广泛使用大型WPF/Silverlight/WP8/WinRT应用程序,您也可以在视图模型中使用handy和universalcaliburn的
Execute.InDesignMode
静态属性(它在Blend中的效果与在Visual Studio中一样好):
使用Caliburn.Micro;
// ...
///
///不带参数的默认视图模型的ctor。
///
公共视图模型()
{
if(Execute.InDesignMode)
{
//仅在此处添加设计时的假数据:
//SomeStringItems=新列表
//{
//“项目1”,
//“项目2”,
//“项目3”
//};
}
}
在任何地方工作。我使用它来阻止数据绑定视频在设计器中播放。在WPF中指定设计时数据还有其他(可能更新的)方法,如下所示
基本上,您可以使用以下命令指定设计时数据:
或通过:
您必须将SamplePage.xaml
文件属性设置为:
BuildAction: DesignData
Copy to Output Directory: Do not copy
Custom Tool: [DELETE ANYTHING HERE SO THE FIELD IS EMPTY]
我将它们放在我的UserControl
标记中,如下所示:
//pseudo code:
if (Application.Current.ExecutingStatus == ExecutingStatus.DesignMode)
{
...
}
DesignerProperties.GetIsInDesignMode(new DependencyObject());
<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="...">
我只在VisualStudio2013和.NET4.5中测试过这一点,但它确实做到了
public static bool IsDesignerContext()
{
var maybeExpressionUseLayoutRounding =
Application.Current.Resources["ExpressionUseLayoutRounding"] as bool?;
return maybeExpressionUseLayoutRounding ?? false;
}
尽管VisualStudio中的某些设置可能会将此值更改为false,但如果发生这种情况,我们可以只检查此资源名称是否存在。当我在设计器之外运行代码时,它是null
这种方法的优点是,它不需要明确了解特定的
App
类,并且可以在整个代码中全局使用。特别是用虚拟数据填充视图模型。如果您的类不需要空构造函数,我有一个主意
其思想是创建一个空构造函数,然后用ObsoleteAttribute标记它。设计器会忽略过时属性,但如果您尝试使用它,编译器将引发错误,因此您自己不会意外使用它
()
公共类SomeClass
公共分新()
设计模式=真
如果是设计模式,那么
Name=“宝拉很聪明”
如果结束
端接头
公共属性设计模式为布尔型
公共属性名称为String=“FileNotFound”
末级
以及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>
如果你真的需要空的构造函数来做其他事情,这就不起作用了。接受的答案对我不起作用(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");
}
}
作为旁注,IsInDesignMode实际上是一个附加属性,因此您也可以在xaml的绑定中使用它。可能不是最常用的用法:)感谢您使用最新的XAML“应用程序”(如WinRT和WP)更新答案。在VS2019中,必须启用开关
Enable project code
(或菜单->设计->此方法也可使ViewModels设计器友好(因为它们本身不是依赖对象).DependencyObject具有受保护的构造函数-定义内部类MyDependencyObject:DependencyObject{}并使用新建MyDependencyObject
而不是DependencyObject
@ricoster:如果在viewmodel中执行此操作,您可能希望将其抽象为一个静态类,并将结果存储为上述应用程序的静态布尔值。Current.MainWindow==null
虽然我更喜欢类型测试,但更多直接。它还显示为Visual Studio中托管的设计器添加了资源,因此这里有另一种方法(如果您无法访问托管代码的库中的特定应用程序类型)((bool)应用程序.Current.resources[“ExpressionUseLayoutRounding”])
。需要检查资源是否不存在,但它是否在设计器上下文中工作。此答案在任何地方都不起作用。例如,在库中,您没有App类。;)这对我有效,我需要知道我是否在设计时从viewModel中运行,并且无法使用Windows库。我知道这是一个非常小的问题
<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>
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");
}
}