Howto avoid a “object reference not set to an inst

2020-06-08 14:54发布

问题:

I have a problem with a wpf usercontrol which is of my own devising. The problem is that i get a object reference not set to an instance of an object exception in XAML code while design time, when I implement the usercontrol in my program.

How can i fix or suppress the exeption?

EDIT 1

The designer show me following information:

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)

I think they are not really helpful...

回答1:

If you have 'Object reference not set to an instance of an object' in XAML, but your application compiles and runs fine, you will usually find out that its cause is something in a constructor that can't be resolved at design time.

You can just click the "Disable project code" button located on the bottom of your designer view and Visual Studio designer will stop trying to construct an instance to provide design time data view.

See here for detailed information and screenshots.



回答2:

Whatever is happening in your constructor is throwing an exception during design time. I had same problem - I just put a try catch around the problematic code - in my case I was calling ServiceLocator.Current as I am using an IoC container. But there is no container during design time. So I wrapped in a try catch to suppress the error and it worked. Not the best solution... but its a solution.



回答3:

I tend to use the LicenseManager class in System.ComponentModel to avoid my ViewModels throwing nasty errors at designtime. For example:

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


回答4:

Tweaking @BobHorn's example, I got this to work for me:

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

Though using his exact suggestion for the constructor

public Main()
{
    if (IsInDesignMode) { return; }
    //Constructor code here...
}

Did also work for me, I just prefer not short-circuiting my methods with extra return statements. I would have up-voted his answer, don't have the rep yet.



回答5:

You could do something like this:

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

Then, as the first line in the constructor of your view (or view model), you can do something like this:

if (DesignMode.IsInDesignMode) { return; }

That way your code will only run when you're actually running it.



回答6:

I had the similar problem. You just need to go to Tools> Options> XAML Designer and enable the option

"Run project code in XAML designer".

Finally restart Visual Studio. I hope this will help.



回答7:

VS 2017 UWP:

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


回答8:

In you "partial class" of XAML, if you can see " [XamlCompilation(XamlCompilationOptions.Compile)]", just remove the line, and then try build again.



回答9:

If someone else comes here, I had inadvertently dragged my MainWindow.xaml file to a sub folder. Dragging it back fixed the problem.



回答10:

When you work on a WIndow/UserControl in the designer it "runs" the parameterless constructor. If you have code in there which is reliant on something usually provided by some other piece of code then this often causes a problem. The designer doesn't run any other code first so dependencies usually provided elsewhere can be missing and cause errors. Suppressing these is a matter of detecting whether that code is running in the designer or not. It's often most convenient to just return out the constructor:

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

    //code
}

More in detail https://social.technet.microsoft.com/wiki/contents/articles/29874.aspx?Redirected=true



回答11:

Change the "Build only" option to "Intellisense only" in the error list window