我自己设计的 wpf 用户控件有问题。 问题是,当我在我的程序中实现用户控件时,我在设计时在 XAML 代码中遇到
object reference not set to an instance of an object
异常。
设计师向我展示了以下信息:
at
Microsoft.Expression.Platform.InstanceBuilders.InstanceBuilderOperations.InstantiateType(Type
type, Boolean supportInternal) at
Microsoft.Expression.Platform.InstanceBuilders.ClrObjectInstanceBuilder.InstantiateTargetType(IInstanceBuilderContext
context, ViewNode viewNode) at
Microsoft.Expression.Platform.InstanceBuilders.ClrObjectInstanceBuilder.Instantiate(IInstanceBuilderContext
context, ViewNode viewNode) at
Microsoft.Expression.WpfPlatform.InstanceBuilders.FrameworkElementInstanceBuilder.Instantiate(IInstanceBuilderContext
context, ViewNode viewNode) at
Microsoft.Expression.WpfPlatform.InstanceBuilders.UserControlInstanceBuilder.Instantiate(IInstanceBuilderContext
context, ViewNode viewNode) at
Microsoft.Expression.Platform.InstanceBuilders.ViewNodeManager.CreateInstance(IInstanceBuilder
builder, ViewNode viewNode)
但我认为这些消息并不是很有帮助...
如何修复或抑制此异常?
如果您在 XAML 中有“对象引用未设置为对象的实例”,但您的应用程序编译并运行良好,您通常会发现其原因是构造函数中无法在设计时解决的问题。
您只需单击设计器视图底部的“禁用项目代码”按钮,Visual Studio 设计器将停止尝试构建实例以提供设计时数据视图。
有关详细信息和屏幕截图,请参阅此处。
构造函数中发生的任何事情都会在设计时抛出异常。我遇到了同样的问题——我只是尝试捕获有问题的代码——在我的例子中,我正在调用 ServiceLocator.Current,因为我正在使用 IoC 容器。但是在设计时没有容器。所以我包裹在一个 try catch 中以抑制错误并且它起作用了。不是最好的解决方案......但它是一个解决方案。
我倾向于在
LicenseManager
中使用 System.ComponentModel
类来避免我的 ViewModels 在设计时抛出讨厌的错误。例如:
public MyViewModel()
{
if (LicenseManager.UsageMode == LicenseUsageMode.Runtime)
{
// Do runtime stuff
}
}
调整@BobHorn 的例子,我得到了这个为我工作:
public class ViewModel
{
public ViewModel()
{
if (!IsInDesignMode)
{
//Constructor code here...
}
}
public bool IsInDesignMode
{
get
{
var prop = DesignerProperties.IsInDesignModeProperty;
return (bool)DependencyPropertyDescriptor
.FromProperty(prop, typeof(FrameworkElement))
.Metadata.DefaultValue;
}
}
}
尽管使用了他对构造函数的确切建议
public Main()
{
if (IsInDesignMode) { return; }
//Constructor code here...
}
也对我有用,我只是不想用额外的返回语句来缩短我的方法。我会赞成他的回答,还没有代表。
当您在设计器中处理 WIndow/UserControl 时,它会“运行”无参数构造函数。 如果您的代码依赖于通常由其他代码段提供的内容,那么这通常会导致问题。 设计人员不会首先运行任何其他代码,因此通常在其他地方提供的依赖项可能会丢失并导致错误。 抑制这些是检测该代码是否在设计器中运行的问题。 返回构造函数通常最方便:
public MainWindow()
{
InitializeComponent();
if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
return;
//code
}
更详细https://social.technet.microsoft.com/wiki/contents/articles/29874.aspx?Redirected=true
你可以这样做:
using System.ComponentModel;
using System.Windows;
/// <summary>
/// WPF Design Mode helper class.
/// </summary>
public static class DesignMode
{
private static bool? _isInDesignMode;
/// <summary>
/// Gets a value indicating whether the control is in design mode (running in Blend
/// or Visual Studio).
/// </summary>
public static bool IsInDesignMode
{
get
{
if (!_isInDesignMode.HasValue)
{
var prop = DesignerProperties.IsInDesignModeProperty;
_isInDesignMode
= (bool)DependencyPropertyDescriptor
.FromProperty(prop, typeof(FrameworkElement))
.Metadata.DefaultValue;
}
return _isInDesignMode.Value;
}
}
}
然后,作为视图(或视图模型)构造函数的第一行,您可以这样做:
if (DesignMode.IsInDesignMode) { return; }
这样你的代码只会在你实际运行它时运行。
我有类似的问题。您只需要转到工具>选项> XAML设计器并启用选项
“在 XAML 设计器中运行项目代码”。
最后重启Visual Studio。我希望这会有所帮助。
VS 2017 UWP:
if (false == Windows.ApplicationModel.DesignMode.DesignModeEnabled)
{
// Anything in here need not be OK at Design time in Visual Studio
}
在 XAML 的“部分类”中,如果可以看到“
[XamlCompilation(XamlCompilationOptions.Compile)]
”,
只需删除该行,然后再次尝试构建。
如果其他人来到这里,我无意中将我的 MainWindow.xaml 文件拖到子文件夹中。把它拖回去解决了这个问题。
在错误列表窗口中将“Build only”选项更改为“Intellisense only”
在重构期间,某些类的 C# 名称空间发生了变化。
xmlns
名称也相应更改。
但是在一个地方
xmlns
被改变了它不应该是的地方。例如,这样的代码:
<OldNS:SomeControl ... />
被错误地改为
<NewNS:SomeControl ... />
控件
SomeControl
因此不存在于 NewNS
映射指示的命名空间中。
我没有将此标记为特定错误,而是出于某种原因得到了“对象引用未设置到对象的实例”异常,而不知道来源。
最终找到并修复这个错误,问题就解决了。
对于 XAML 中的某些组件(如 TabControl),VS2022 17.5.4 是否存在此问题(此问题仅在最近的 vs 更新后发生)
从谷歌找到这个解决方案:
然后注意到@windowsill评论也提到了这个 如何在设计时避免 XAML 代码中的“对象引用未设置到对象的实例”异常?