防止 WPF 用户控件在设计模式下呈现
防止 WPF 用户控件在设计模式下呈现
有没有人知道是否有一些全局状态变量可用,以便我可以检查代码当前是否在设计模式下执行(例如,在Blend或Visual Studio中)?
它将类似于这样:
//伪代码:
if(Application.Current.ExecutingStatus == ExecutingStatus.DesignMode)
{
...
}
我需要这个的原因是:当我的应用程序在Expression Blend的设计模式下显示时,我希望ViewModel使用一个“设计客户类”,其中包含设计师可以在设计模式下查看的模拟数据。
然而,当应用程序实际执行时,我当然希望ViewModel使用返回真实数据的真实客户类。
目前,我通过要求设计师在工作之前进入ViewModel并将“ApplicationDevelopmentMode.Executing”更改为“ApplicationDevelopmentMode.Designing”来解决这个问题:
public CustomersViewModel()
{
_currentApplicationDevelopmentMode = ApplicationDevelopmentMode.Designing;
}
public ObservableCollection
{
get
{
try
{
if(_currentApplicationDevelopmentMode == ApplicationDevelopmentMode.Developing)
{
return Customer.GetAll;
}
else
{
return CustomerDesign.GetAll;
}
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
}
}
问题出现的原因是在设计模式下,WPF用户控件仍然会被渲染,这可能会导致一些不必要的行为,如播放数据绑定的视频。为了避免这种情况,我们需要找到一种方法来判断当前是否处于设计模式,然后在设计模式下禁止渲染用户控件。
解决方法之一是使用以下代码来判断是否处于设计模式:
public static bool InDesignMode() { return !(Application.Current is App); }
这个方法可以从任何地方调用,用于停止在设计器中播放数据绑定的视频。它通过检查当前的Application实例是否为App类型来判断是否处于设计模式。
另一种方法是使用以下代码来判断是否处于设计模式:
Application.Current.MainWindow == null
这种方法也可以达到相同的效果,但是我更喜欢类型检测的方式,因为它更直接。
如果你无法访问特定的App类型,还可以使用以下代码(如果资源中存在ExpressionUseLayoutRounding):
((bool)Application.Current.Resources["ExpressionUseLayoutRounding"])
但是需要注意,如果资源不存在,需要进行检查。这种方法在设计器环境中也可以工作。
然而,在某些情况下,上述方法并不适用。例如,在库中,你没有App类。如果你需要在App的静态构造函数中检查是否处于设计模式,这种方法是正确的。
总结起来,要防止WPF用户控件在设计模式下被渲染,我们可以使用上述的代码片段来判断是否处于设计模式,并采取相应的措施来禁止渲染用户控件。这样可以避免一些不必要的行为,并提高设计和开发效率。
使用DesignerProperties.GetIsInDesignMode(new DependencyObject())
方法可以防止WPF用户控件在设计模式下渲染。
这个方法对于使ViewModels在设计时友好也很有效(因为它们本身不是DependencyObjects)。
DependencyObject有一个受保护的构造函数 - 定义internal class MyDependencyObject : DependencyObject {}
并使用new MyDependencyObject
代替DependencyObject
。
如果在ViewModel中这样做,可能会将其封装到一个静态类中并将结果存储为静态布尔值。
问题的原因:在WPF中,用户控件在设计模式下也会被渲染,这可能会导致不必要的性能开销或错误。
解决方法:使用DesignerProperties类的GetIsInDesignMode方法来检查控件是否处于设计模式下。代码示例如下:
// 'this'是你的UI元素 DesignerProperties.GetIsInDesignMode(this);
另外,当使用Silverlight/WP7时,应该使用IsInDesignTool属性,因为GetIsInDesignMode可能在Visual Studio中返回false。代码示例如下:
DesignerProperties.IsInDesignTool;
最后,在WinRT/Metro/Windows Store应用中,可以使用DesignModeEnabled属性来判断是否处于设计模式下。代码示例如下:
Windows.ApplicationModel.DesignMode.DesignModeEnabled;
需要注意的是,IsInDesignMode实际上是一个附加属性,因此也可以在XAML中使用绑定。不过这可能不是最常见的用法。
在VS2019中,还需要确保启用了"Enable project code"选项(或者在菜单中选择Design -> Run Project Code)才能正常工作。