C# 有没有办法检查 WPF 当前是否在设计模式下执行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/834283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to check if WPF is currently executing in design mode or not?
提问by Edward Tanguay
Does anyone know of some global state variable that is available so that I can check if the code is currently executing in design mode (e.g. in Blend or Visual Studio) or not?
有谁知道一些可用的全局状态变量,以便我可以检查代码当前是否在设计模式下(例如在 Blend 或 Visual Studio 中)执行?
It would look something like this:
它看起来像这样:
//pseudo code:
if (Application.Current.ExecutingStatus == ExecutingStatus.DesignMode)
{
...
}
The reason I need this is: when my application is being shown in design mode in Expression Blend, I want the ViewModel to instead use a "Design Customer class" which has mock data in it that the designer can view in design mode.
我需要这样做的原因是:当我的应用程序在 Expression Blend 中以设计模式显示时,我希望 ViewModel 使用“设计客户类”,其中包含设计人员可以在设计模式下查看的模拟数据。
However, when the application is actually executing, I of course want the ViewModel to use the real Customer class which returns real data.
但是,当应用程序实际执行时,我当然希望 ViewModel 使用返回真实数据的真实 Customer 类。
Currently I solve this by having the designer, before he works on it, go into the ViewModel and change "ApplicationDevelopmentMode.Executing" to "ApplicationDevelopmentMode.Designing":
目前我通过让设计师解决这个问题,在他开始工作之前,进入 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);
}
}
}
采纳答案by Richard Szalay
I believe you are looking for GetIsInDesignMode, which takes a DependencyObject.
我相信您正在寻找GetIsInDesignMode,它需要一个 DependencyObject。
Ie.
IE。
// 'this' is your UI element
DesignerProperties.GetIsInDesignMode(this);
Edit:When using Silverlight / WP7, you should use IsInDesignTool
since GetIsInDesignMode
can sometimes return false while in Visual Studio:
编辑:使用 Silverlight / WP7 时,您应该使用,IsInDesignTool
因为GetIsInDesignMode
在 Visual Studio 中有时会返回 false:
DesignerProperties.IsInDesignTool
Edit:And finally, in the interest of completeness, the equivalent in WinRT / Metro / Windows Store applications is DesignModeEnabled
:
编辑:最后,为了完整起见,WinRT / Metro / Windows Store 应用程序中的等效项是DesignModeEnabled
:
Windows.ApplicationModel.DesignMode.DesignModeEnabled
回答by Sacha Bruttin
You can do something like this:
你可以这样做:
DesignerProperties.GetIsInDesignMode(new DependencyObject());
回答by Darren
When Visual Studio auto generated some code for me it used
当 Visual Studio 自动为我生成一些代码时,它使用了
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
...
}
回答by Sevenate
And if you extensively use Caliburn.Microfor your large WPF / Silverlight / WP8 / WinRTapplication you could use handy and universalcaliburn's Execute.InDesignMode
static property in your view-models as well (and it works in Blend as good as in Visual Studio):
如果您在大型WPF/Silverlight/WP8/WinRT应用程序中广泛使用Caliburn.Micro,您也可以在视图模型中使用方便且通用的caliburn静态属性(它在 Blend 中和 Visual Studio 中一样好用):Execute.InDesignMode
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"
//};
}
}
回答by Patrick
public static bool InDesignMode()
{
return !(Application.Current is App);
}
Works from anywhere. I use it to stop databound videos from playing in the designer.
从任何地方工作。我用它来阻止数据绑定视频在设计器中播放。
回答by cod3monk3y
There are other (maybe newer) ways of specifying design-time data in WPF, as mentioned in this related answer.
如本相关答案中所述,还有其他(可能是更新的)方法可以在 WPF 中指定设计时数据。
Essentially, you can specify design-time data using a design-time instance of your ViewModel:
本质上,您可以使用ViewModel的设计时实例指定设计时数据:
d:DataContext="{d:DesignInstance Type=v:MySampleData, IsDesignTimeCreatable=True}"
or by specifying sample data in a XAML file:
或通过在 XAML 文件中指定示例数据:
d:DataContext="{d:DesignData Source=../DesignData/SamplePage.xaml}">
You have to set the SamplePage.xaml
file properties to:
您必须将SamplePage.xaml
文件属性设置为:
BuildAction: DesignData
Copy to Output Directory: Do not copy
Custom Tool: [DELETE ANYTHING HERE SO THE FIELD IS EMPTY]
I place these in my UserControl
tag, like this:
我将这些放在我的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="...">
At run-time, all of the "d:" design-time tags disappear, so you'll only get your run-time data context, however you choose to set it.
在运行时,所有“d:”设计时标记都消失了,因此您只能获得运行时数据上下文,无论您选择如何设置它。
EditYou may also need these lines (I'm not certain, but they seem relevant):
编辑您可能还需要这些行(我不确定,但它们似乎相关):
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
回答by John Leidegren
I've only tested this with Visual Studio 2013 and .NET 4.5 but it does the trick.
我只用 Visual Studio 2013 和 .NET 4.5 测试过这个,但它确实有效。
public static bool IsDesignerContext()
{
var maybeExpressionUseLayoutRounding =
Application.Current.Resources["ExpressionUseLayoutRounding"] as bool?;
return maybeExpressionUseLayoutRounding ?? false;
}
It's possible though that some setting in Visual Studio will change this value to false, if that ever happens we can result to just checking whether this resource name exist. It was null
when I ran my code outside the designer.
尽管 Visual Studio 中的某些设置可能会将此值更改为 false,但如果发生这种情况,我们可以仅检查此资源名称是否存在。那是null
我在设计器之外运行我的代码的时候。
The upside of this approach is that it does not require explicit knowledge of the specific App
class and that it can be used globally throughout your code. Specifically to populate view models with dummy data.
这种方法的优点是它不需要特定App
类的明确知识,并且可以在整个代码中全局使用。专门用虚拟数据填充视图模型。
回答by DonkeyMaster
I have an idea for you if your class doesn't need an empty constructor.
如果您的类不需要空的构造函数,我有一个想法。
The idea is to create an empty constructor, then mark it with ObsoleteAttribute. The designer ignores the obsolete attribute, but the compiler will raise an error if you try to use it, so there's no risk of accidentaly using it yourself.
这个想法是创建一个空的构造函数,然后用 ObsoleteAttribute 标记它。设计者会忽略 obsolete 属性,但是如果您尝试使用它,编译器会引发错误,因此不存在自己意外使用它的风险。
(原谅我的视觉基础)
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
And the xaml:
和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>
This won't work if you reallyneed the empty constructor for something else.
如果你真的需要空的构造函数来做其他事情,这将不起作用。
回答by Ger Hobbelt
Accepted answer didn't work for me (VS2019).
接受的答案对我不起作用(VS2019)。
After inspecting what was going on, I came up with this:
在检查了发生了什么之后,我想出了这个:
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");
}
}