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