【问题标题】:How to avoid a "object reference not set to an instance of an object" exception in XAML code at design time?如何在设计时避免 XAML 代码中的“对象引用未设置为对象的实例”异常?
【发布时间】:2013-07-16 02:38:07
【问题描述】:

我自己设计的 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)

但我认为这些消息并没有真正的帮助......

如何修复或抑制此异常?

【问题讨论】:

  • 设计师应该向您展示错误的堆栈跟踪 - 错误实际发生在哪里?
  • 请贴出引发错误的代码部分。提供的信息很难回答这个问题
  • 是的,我知道另一个问题,但没有任何描述的解决方案可以解决我的问题。在问这个问题之前,我阅读了另一个问题。

标签: c# wpf exception user-controls


【解决方案1】:

如果您在 XAML 中设置了“未将对象引用设置为对象的实例”,但您的应用程序编译并运行良好,您通常会发现其原因是构造函数中无法在设计时解决的问题时间。

您只需单击位于设计器视图底部的“禁用项目代码”按钮,Visual Studio 设计器将停止尝试构造实例以提供设计时数据视图。

有关详细信息和屏幕截图,请参阅here

【讨论】:

  • 如果当前xaml上的设计器没有加载,“禁用项目代码”按钮将不可用。加载一个好的 xaml 以使按钮可用。该设置现在将应用于拒绝加载的 xaml。
  • 如果您没有看到按钮,请尝试评论 propblamitc 行,然后您会得到它
  • 我的构造函数中有一些代码导致了这种现象的发生 - 它困扰着我(可以这么说)很高兴你在这里帮助了我。
  • 在我的 VS 中,该按钮让我可以选择“显示所有控件”或“仅显示平台控件”。选择后者会导致 xaml 在设计器中呈现并删除未设置为对象错误实例的对象引用。
【解决方案2】:

在您的构造函数中发生的任何事情都会在设计时引发异常。我遇到了同样的问题 - 我只是在有问题的代码周围尝试了一下 - 在我的情况下,我正在调用 ServiceLocator.Current,因为我正在使用 IoC 容器。但是在设计时没有容器。所以我包裹了一个try catch来抑制错误并且它起作用了。不是最好的解决方案......但它是一个解决方案。

【讨论】:

  • 这个答案是 0 意义。问题出在 XAML 中,没有办法“只是尝试捕获”。如果一个人知道“有问题的代码”是什么,就不会有问题。
  • @N_tro_P xaml 后面有一个 .cs 文件,它有一个构造函数。
  • 你认为在 InitializeComponent() 周围包裹一个 try catch 会捕获有问题的代码吗?另外...某些 XAML 没有构造函数,例如资源字典。这尤其是我的情况以及我是如何来到这里的。
  • 我不认为 .Net 设计时错误在乎你的信念。同样,后面甚至没有必要的代码。也许在海报案例中,正如他在细节中所说的“用户控制”,但问题是如何处理 XAML 中的设计时错误,这也可能是 RD。在这种情况下没有构造函数。
  • 也许它不适用于您的情况。我认为,如果您分享您的具体情况以及如何解决它,那将比花言巧语更有成效。
【解决方案3】:

我倾向于在System.ComponentModel 中使用LicenseManager 类来避免我的ViewModel 在设计时抛出令人讨厌的错误。例如:

public MyViewModel()
{
  if (LicenseManager.UsageMode == LicenseUsageMode.Runtime)
  {
    // Do runtime stuff
  }
}

【讨论】:

    【解决方案4】:

    调整@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...
    }
    

    也对我有用,我只是不想用额外的 return 语句来短路我的方法。我会投票赞成他的答案,但还没有代表。

    【讨论】:

      【解决方案5】:

      你可以这样做:

      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; }
      

      这样您的代码只会在您实际运行时运行。

      【讨论】:

        【解决方案6】:

        我遇到了类似的问题。您只需要转到 Tools> Options> XAML Designer 并启用该选项

        “在 XAML 设计器中运行项目代码”。

        最后重新启动 Visual Studio。我希望这会有所帮助。

        【讨论】:

        • 您使用的是哪个版本的 Visual Studio?我在 Visual Studio 2013 中找不到“XAML 设计器”部分。
        • 抱歉来晚了。无论如何,我使用的是 VS 2015。
        • 啊啊,来晚了,对 :) 我确实在最近的 VS 版本中发现了这个选项。
        • 所以每两年一个答案? :b 我正在使用 VS 2019,在 XAML 设计器菜单中找不到该选项..
        【解决方案7】:

        当您在设计器中处理 WIndow/UserControl 时,它会“运行”无参数构造函数。 如果你的代码依赖于其他一些代码通常提供的东西,那么这通常会导致问题。 设计器不会首先运行任何其他代码,因此通常在其他地方提供的依赖项可能会丢失并导致错误。 抑制这些是检测该代码是否在设计器中运行的问题。 只返回构造函数通常是最方便的:

        public MainWindow()
        {
            InitializeComponent();
            if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
                return;
        
            //code
        }
        

        更多详情https://social.technet.microsoft.com/wiki/contents/articles/29874.aspx?Redirected=true

        【讨论】:

          【解决方案8】:

          VS 2017 UWP:

          if (false == Windows.ApplicationModel.DesignMode.DesignModeEnabled)
          {
               // Anything in here need not be OK at Design time in Visual Studio                 
          }
          

          【讨论】:

            【解决方案9】:

            在你 XAML 的“部分类”中,如果你能看到“[XamlCompilation(XamlCompilationOptions.Compile)]”, 只需删除该行,然后再次尝试构建。

            【讨论】:

              【解决方案10】:

              如果其他人来到这里,我无意中将我的 MainWindow.xaml 文件拖到了一个子文件夹中。将其拖回即可解决问题。

              【讨论】:

                【解决方案11】:

                在错误列表窗口中将“仅构建”选项更改为“仅智能感知”

                【讨论】:

                  【解决方案12】:

                  在重构期间,某些类的 C# 命名空间发生了变化。 xmlns 名称也相应更改。

                  然而,xmlns 在一个地方被更改了它不应该在的地方。例如,这样的代码:

                  <OldNS:SomeControl ... />
                  

                  被错误地更改为

                  <NewNS:SomeControl ... />
                  

                  因此,NewNS 映射指示的命名空间中不存在控件 SomeControl

                  我没有将其标记为特定错误,而是出于某种原因得到了“对象引用未设置为对象的实例”异常,而不知道来源。

                  最终发现并修复了这个错误解决了问题。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-08-04
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-08-08
                    相关资源
                    最近更新 更多