Visual Studio 2008 IDE无法正确呈现自定义控件

我在设计时遇到了Visual Studio 2008中所有表单和自定义控件的问题。直到上一次检入,所有控件都按预期呈现。 当前版本和上一个工作版本之间唯一的主要区别是控件UIText上的属性已从Content重命名为Value 。 其他更改是添加一个新表单和3个新枚举,但肯定没有明显的变化会影响程序中的所有表单(包括新表单)。

所有控件(在每个窗体上)现在都呈现为一个带有控件名称的框(但它们都在运行时正确呈现):

渲染问题

我已经尝试在我的项目中创建一个全新的表单,创建一个全新的自定义控件,上面只有一个标签,我仍然有完全相同的问题:

奇异的

请注意,标准.Net表单控件工作正常,因此这只是自定义控件的问题。

如果我从存储库中恢复以前的版本,那么一切都会再次开始正确呈现:

正确渲染

我可以恢复到这个工作版本并继续,但我宁愿知道如果它再次发生如何解决问题。 我在这里发帖,希望它是一个与Visual Studios 2008问题相关的编程问题(顺便提一下SP1)。

更新 – 问题跟踪,无法解释

解决了这个问题。 好吧,固定不是真正合适的词。 我通过一次删除所有用户控件1找到问题,直到表单再次正确开始渲染。 这个问题出现在我的Signature控件中(已存在多年,只有在我最近的检查中,我已将项目iVirtualDocket.CodeLibrary的引用添加到主项目中:

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

签名有一个名为SignatureData的属性,它正在这样做:

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

ImageToByteArray如下所示:

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

如果我将上述方法移动到UIControls项目中,那么一切正常。 但是,只要我将该方法放回CodeLibrary项目并在那里调用它,我的所有表单都会停止呈现UserControls。

所以做以下事情可以解决问题,但我真的想知道原因:

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

(更奇怪的是,我甚至没有使用这个属性。)

我们的应用程序具有类似的非设计时显示问题。 通过做一些研究(我不记得我们找到它的确切位置),我们最终创建了一个文件

DesignTimeAttributes.xmta

它的类型是“设计时属性文件”的类型

在其中,我们只需要声明我们定义的每个控件类,并将其限定为“DesktopCompatible”。 这样它显然告诉设计师可以绘制,并且某些控件中的实际function(对于我们来说也是手持扫描器上的签名控件)实际上会在运行时调用设计器中没有的东西。 该文件的内容类似于……

    true   true   true   

除了提供csauve的回答之外,这也是一个补充。 如果你的构造函数试图初始化依赖于设备的东西,从而抛出一个错误,因为设计时间显然不具备设备dll,控件或任何可能/也会在设计时杀死该控件。 我们创建了两个静态函数来测试两种方式

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

并在构造函数中分别调用它们……

我想也许你需要让你的控件知道它们何时处于设计模式。 如果可以避免,您的控件的无参数构造函数不应执行任何昂贵或具有副作用的操作(即从磁盘加载文件)。

我假设你的截图是你正在使用WPF。 我相信设计模式可以使用DesignerProperties.GetIsInDesignMode(this)来确定

请参阅http://msdn.microsoft.com/en-us/library/system.componentmodel.designerproperties.getisindesignmode.aspx

 public partial class MyControl : UserControl { public MyControl() { InitializeComponent(); if (!DesignerProperties.GetIsInDesignMode(this)) { //Do expensive operations here } } } 

您可能还希望阅读http://blogs.msdn.com/b/jgalasyn/archive/2007/10/29/troubleshooting-wpf-designer-load-failures.aspx