Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual studio 2008 IDE not rendering Custom Controls correctly

I'm having an issue at design time with all my forms and custom controls within Visual Studios 2008. Up until the previous check in, all of the controls were rendering as expected. The only main difference between the current version and the previous working version was that a Property on the control UIText was renamed from Content to Value. The other changes are adding a new form and 3 new enums, but there's certainly no obvious change that would affect all forms in the program (including new ones).

All of the controls (on every form) now render as a box with the name of the control (however they all render correctly at run time):

Rendering Issue

I've tried creating a brand new form in my project, creating a brand new custom control with just a label on it, and I've still got exactly the same problem:

Bizarre

Note that standard .Net form controls work fine, so this is only an issue with custom controls.

If I restore my previous version from the repository, then everything starts rendering correctly again:

Rendering Correctly

I could just revert back to this working version and carry on, but I'd rather know how to fix the problem should it occur again. I'm posting here hoping it's a programming issue as apposed to a Visual Studios 2008 issue (on SP1 by the way).

UPDATE - Issue traced, can't explain it

I fixed the issue. Well, fixed isn't really the right word for it. I located the issue by removing all of the user controls 1 at a time until the form started rendering properly again. The issue was in my Signature control (which has been present for ages, only in my latest check in I had added a reference to the project iVirtualDocket.CodeLibrary into the main project:

  iVirtualDocket
    - References iVirtualDocket.UIControls
    - References iVirtualDocket.CodeLibrary
  iVirtualDocket.UIControls
    -References iVirtualDocket.CodeLibrary

The signature has a property called SignatureData, which was doing this:

public byte[] SignatureData
{
    get
    {
        if (_signature == null)
        {
            return null;
        }
        else
        {
            return iVirtualDocket.CodeLibrary.Conversions.ImageToByteArray(
                _signature, ImageFormat.Png);
        }
    }
}

ImageToByteArray looks like the following:

public static byte[] ImageToByteArray(Image imageToConvert,
        ImageFormat formatOfImage)
{
    byte[] ret;
    using (MemoryStream ms = new MemoryStream())
    {
        imageToConvert.Save(ms, formatOfImage);
        ret = ms.ToArray();
    }

    return ret;
}

If I move the above method into the UIControls project, then everything works fine. However, as soon as I put the method back into the CodeLibrary project and call it there, all my forms stop rendering UserControls.

So doing the following fixes the problem, but I'd really like to know why:

public byte[] SignatureData
{
    get
    {
        if (_signature == null)
        {
            return null;
        }
        else
        {
            // Need to call this code directly here instead of through 
            // the CodeLibrary conversions, otherwise all user controls stop 
            // rendering in design mode
            byte[] ret;
            using (MemoryStream ms = new MemoryStream())
            {
                _signature.Save(ms, ImageFormat.Png);
                ret = ms.ToArray();
            }

            return ret;
        }
    }
}

(What's even more bizarre is that I don't even use this property yet.)

like image 597
djdd87 Avatar asked Nov 05 '22 02:11

djdd87


1 Answers

We have an application that had similar non-design-time display problems. By doing some research (and I don't remember exactly where we found it), we ended up creating a file

DesignTimeAttributes.xmta

Its type is that of "Design-Time Attribute File"

and in it, we just had to declare each of the control classes we had defined and qualified it as "DesktopCompatible". This way it apparently tells the designer its ok to draw, and the actual functionality within some controls (also a signature control on a handheld scanner for us), would actually invoke something during runtime that was not available in the designer. The content of the file was something like...

<?xml version="1.0" encoding="utf-16"?>
<Classes xmlns="http://schemas.microsoft.com/VisualStudio/2004/03/SmartDevices/XMTA.xsd">
  <Class Name="MyNamespace.MyControl">
    <DesktopCompatible>true</DesktopCompatible>
  </Class>

  <Class Name="MyNamespace.MyOtherControl">
    <DesktopCompatible>true</DesktopCompatible>
  </Class>

  <Class Name="AnotherNamespace.MySignControl">
    <DesktopCompatible>true</DesktopCompatible>
  </Class>
</Classes>

This was also in addition to the comments provided csauve's answer. If your constructor is trying to initialize something that is device dependent and thus throws an error because the design-time doesn't obviously have the device dlls, controls, or whatever could/would also kill that control at design time. We've created two static functions to test either way via

public static bool IsDesignTime()
{
  return System.ComponentModel.LicenseManager.UsageMode ==
         System.ComponentModel.LicenseUsageMode.Designtime;
}

public static bool IsRunTime()
{
  return System.ComponentModel.LicenseManager.UsageMode ==
         System.ComponentModel.LicenseUsageMode.Runtime;
}

and call them respectively in the constructors...

like image 90
DRapp Avatar answered Nov 10 '22 15:11

DRapp