Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有没有办法检查WPF当前是否在设计模式下执行?_C#_Wpf_Expression Blend - Fatal编程技术网

C# 有没有办法检查WPF当前是否在设计模式下执行?

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

是否有人知道一些可用的全局状态变量,以便我可以检查代码当前是否以设计模式(如Blend或Visual Studio)执行?

它看起来像这样:

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