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):
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:
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:
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).
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.)
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With