views:

162

answers:

4

Hi,

Let's say I have a projoct A with a class A that has this property:

    public bool IsConnected
    {
        get { return m_isConnected; }
        private set { m_isConnected = value; }
    }

In the same solution, I have a project B that references project A and has a user control called Login. This control has this attribute:

    private A m_A = null;

and in the contructor of Login I do this call:

if (m_A != null && m_A.IsConnected) { ... }

In the same project, the main form has on it a user control A that was added with the form designer. The program runs fine and this property is correctly read.

However, when opening the main form in the Designer I get this execption: MissingMethodException: 'Boolean A.get_IsConnected()'

Commenting out m_A.IsConnected let's me use the designer, but this is getting pretty annoying. And sometimes it seems like it randomly just works.

Any ideas?

A: 

Instead of commenting it out you could use:

if (this.DesignMode)
{
    return;
}

or

if (!this.DesignMode)
{
    if (m_A != null && m_A.IsConnected) { ... }
}

Edit: I remember having problems with a singleton class once. Problem was that the singleton was always initialized although the constructor was never called. If I understand your problem correctly your problem is likewise. Your member m_A is never NULL although it should be.
I managed my problem with the following:
In Visual Studio go to "Tools\Options...\Debugging\General" and disable "Enable property evaluation and other implicit function calls" and enable "Step over properties and operators (Managed only)".
Maybe that helps.

Simon Linder
I was looking for something like this, thanks! Unfortunately, this workaround does not change anything, which is weird. I'll also add that at construction time m_A is always null so the IsConnected property should never be read anyways.
Nicolas Rousseau-Dupuis
Remember to call InitializeComponents() first.
Simon Linder
InitializeComponents() is called first, still get the exception even though !this.DesignMode and m_A != null should both fail.
Nicolas Rousseau-Dupuis
A: 

I've been told in the past that this.DesignMode isn't always perfectly reliable. The other option you can use is preprocessor directives:

#if DESIGN
return;
#else
if (m_A != null && m_A.IsConnected) { /* etc. */ }
#endif

Then add a conditional compilation symbol named DESIGN and you should be golden.

Ari Roth
I'd love to fix the problem at its source, but I'll go for this workaround for now. Thanks!
Nicolas Rousseau-Dupuis
A: 

As noted by Ari Roth DesignMode doesn't work right. To compensate for this, I use this extension method:

public static bool IsDesignTime(this Control control)
{
    if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
    {
        return true;
    }

    if (control.Site != null && control.Site.DesignMode)
    {
        return true;
    }

    var parent = control.Parent;
    while (parent != null)
    {
        if (parent.Site != null && parent.Site.DesignMode)
        {
            return true;
        }
        parent = parent.Parent;
    }
    return false;
}

Use it in the same manner that Simon Linder describes.

fre0n
A: 

It looks like the designer is using an old version of the control DLL, which does not have the IsConnected property.

The MissingMethodException exception is not related to the value of m_A. It is the JIT compiler complaining that the property is missing. If you wrap the call to m_A.IsConnected in a method, it works, because this method is not called (because m_A really is null), thus not jitted, thus the IsConnected property is not needed.

When you put the control in a form in VS, the designer creates a "real" instance of your control in the form, which calls the constructor, which causes the JIT compile problem.

Timores
Wrapping the call in a nother function works just as you say. However I don't understand how the designer could use an old DLL, I did build and rebuild everything many many times...
Nicolas Rousseau-Dupuis
Unfortunately, I don't either. If you had an old version in the GAC, this would explain it, but it would not work at runtime either.I guess you also left VS, deleted the obj and bin directories and re-launched VS.
Timores