Windows 窗体设计器中的设计时错误

在用 VS.NET进行窗体设计的时候,经常会遇到这样的问题:我们需要在构造函数或者在OnLoad事件中进行自己的一些初始化操作,比如连接一个数据库、调用一个资源文件或者后期绑定一个组件。如果代码通过编译,在运行时会执行得相当如你所愿。然而,当我们用窗体设计器打开这样一个窗体或者继承的窗体,IDE环境会抛出非常令人不愉快的异常,比如(NullReferenceException )。

究其原因,主要是窗体设计器在载入窗体时会自动初始化该对象,自动执行诸如构造函数、OnLoad方法和InitializeComponent方法,目的在于能使窗体设计器展现出可视化的编辑操作环境。(一些第三方控件也就是利用这个时机弹出注册认证的)。

现在大家明白了,原来我们通过窗体设计器打开一个窗体类或控件类时,IDE环境已经悄悄地在宿主进程中实例化了我们的类。

如果我们在构造函数中写了这样的代码:

[c-sharp] view plain copy

print?

  1. public class MyClass : System.WIndows.Forms.Form
  2. {
  3. public MyClass(string fileName)
  4. {
  5. InitializeComponent();
  6. FileStream myFile = File.Open( filename ); // 窗体设计器可能抛出异常!
  7. //…
  8. }
  9. //…
  10. }

public class MyClass : System.WIndows.Forms.Form { public MyClass(string fileName) { InitializeComponent(); FileStream myFile = File.Open( filename ); // 窗体设计器可能抛出异常! //… } //… }

问题便由此产生,fileName参数的值是程序在运行时传递的,设计时当然无从获得。所以,窗体设计器在打开此窗体类时,必然会抛出异常,同时窗体将无法正常显示。

解决这种问题的办法网上其他朋友说了很多,归纳起来好像主要有以下三种途径:

一、判断 this.DesignMode 属性
这是让人一眼看过去就觉得最直接最有效的方法,绝对有一种踏破铁蹄无觅处,得来全不费功夫的欣快感——可惜的是,用起来一点不奏效。因为如果该窗体是个独立窗体或控件,那一点问题都没有,DesignMode的值如你所愿为true,但是如果它是包含在其他控件中被拖拽到设计器中(例如,把设计好的控件拖入新的WinForms窗体),那么那个接受拖拽的窗体才处于设计模式,而它不是,它已鬼使神差地进入了RunTime模式,然后如我所愿,抛出异常J。

 

二、利用 Assembly.GetEntryAssembly()方法

判断执行程序入口的组件是不是我们预想的,如果不是,那么必然是IDE的窗体设计器调用的——问题解决——只是有点大炮打蚊子的感觉。

 

三、定义一个静态成员,指示程序所处的模式
此方法我认为最好。具体做法是写一个全局类,也就是构造函数为 private 限制的类,里面的成员都为static静态类型。这样的一个类由于构造函数是私有的,所以不可能自任何地方任何外部代码中实例化,从而保证了其内成员的唯一性。然后,在程序的入口处,把此类的一个用于表示运行模式的静态成员标识为“运行时”,下面….一切都好说了,看代码吧:

[c-sharp] view plain copy

print?

  1. //全局类
  2. public class GlobalClass
  3. {
  4. //私有构造器,防止实例化
  5. private GlobalClass(){}
  6. //用于标识运行时/设计时的bool型静态成员,初始值设为false
  7. public static bool RunTimeMode = false;
  8. }
  9. //包含程序入口的类
  10. Public class Entry
  11. {
  12. //主线程入口点,窗体设计器绝不会执行此方法
  13. static void Main(string[] args)
  14. {
  15. //置为true
  16. GlobalClass.RunTimeMode = true;
  17. //…..
  18. }
  19. //…
  20. }
  21. //某个窗体类
  22. public class MyForm : System.Windows.Forms.Form
  23. {
  24. public MyForm()
  25. {
  26. //窗体设计器必须调用的
  27. InitializeComponent();
  28. //判断运行模式
  29. If( GlobalClass.RunTimeMode )
  30. {
  31. //在此处做一些窗体设计器会报错的事情
  32. }
  33. //…
  34. }
  35. //…
  36. }

//全局类 public class GlobalClass { //私有构造器,防止实例化 private GlobalClass(){} //用于标识运行时/设计时的bool型静态成员,初始值设为false public static bool RunTimeMode = false; } //包含程序入口的类 Public class Entry { … //主线程入口点,窗体设计器绝不会执行此方法 static void Main(string[] args) { //置为true GlobalClass.RunTimeMode = true; //….. } //… } //某个窗体类 public class MyForm : System.Windows.Forms.Form { public MyForm() { //窗体设计器必须调用的 InitializeComponent(); //判断运行模式 If( GlobalClass.RunTimeMode ) { //在此处做一些窗体设计器会报错的事情 } //… } //… } 呵呵,问题圆满解决。其实这样一个全局类在我们平时设计系统的时候会经常用到,多用于存储一些对象间的交互数据或者运行时环境参数。

如果大家有什么更好的办法解决所述问题,记得分享哦 :)

转载自:http://blog.csdn.net/uyi/archive/2006/03/18/628694.aspx

print?

  1. public class MyClass : System.WIndows.Forms.Form

  2. public MyClass(string fileName) 
  3. {  
  4. InitializeComponent(); 
  5. FileStream myFile = File.Open( filename ); // 窗体设计器可能抛出异常! 
  6. //… 
  7. //…

  8. }

public class MyClass : System.WIndows.Forms.Form { public MyClass(string fileName) { InitializeComponent(); FileStream myFile = File.Open( filename ); // 窗体设计器可能抛出异常! //… } //… }

时间: 2024-10-11 20:01:38

Windows 窗体设计器中的设计时错误的相关文章

C#用DesignSurface实现一个简单的窗体设计器

System.ComponentModel.Design.DesignSurface是为设计组件提供一个用户界面,通过它可以实现一个简单的窗体设计器. 在构建之前,我们需要引入System.Design.dll,否则会出现找不到DesignSurface的错误.  1         private void Form1_Load(object sender, EventArgs e) 2         { 3            //引用System.Deisgn.dll 4       

qt设计器中使用自定义控件

当qt设计器中的控件不能满足需要时,这时就要自定义控件.然后再在qt设计器中使用. 在qt设计器中使用自定义控件时,可以用提升. 从控件派生出新的类: 然后在qt设计器中右键需要提升的控件: 填入提升的类: 最后要注意,在工程文件(.pro)中的 INCLUDEPATH 中指定自定义类头文件的位置: INCLUDEPATH += $$PWD/Widgets/FrmCustom (这是本人 CLabel 类的位置) 另外注意: qt设计器中控件的事件会根据实现类中的名称自动连接相应的槽. http

解析大型.NET ERP系统核心组件 查询设计器 报表设计器 窗体设计器 工作流设计器 任务计划设计器

企业管理软件包含一些公共的组件,这些基础的组件在每个新项目立项阶段就必须考虑.核心的稳定不变功能,方便系统开发与维护,也为系统二次开发提供了诸多便利.比如通用权限管理系统,通用附件管理,通用查询等组件,若是在项目开发前就准备好了这些组件,为项目如期交付提供了保证. 查询设计器 Query Designer  支持选择一个或多个数据库表,通过左右连接的方式构建查询结果,支持直接手写SQL语句设计查询,支持调用存储过程查询,支持用代码设计查询. 报表设计器 Report Designer 支持配置的

Winform窗体设计器上的菜单及工具栏上的图标不见恢复解决方案

前段时间有朋友问我,他在设计窗体的时候由于资源文件未找到, 运行后发现窗口中的菜单栏上没有任何菜单项,工具栏上的图标按钮也都不见了, 遇到这种情况,不要急着把该窗体的资源文.设计文件和代码文件删除,否则又要从头开始,得不偿失. 这时,首先看自己的窗体资源文件是否缺少图标文件,打个比方对于窗体BrowseQuestion, 首先打开BrowseQuestion.resx文件,如果没有缺少图标文件,则打开BrowseQuestion.designer.cs文件, 打开窗体设计器自动生成的代码并展开,

C#基础系列:开发自己的窗体设计器(PropertyGrid显示中文属性名)

既然是一个窗体设计器,那就应该能够设置控件的属性,设置属性最好的当然是PropertyGrid了,我们仅仅需要使用一个PropertyGrid.SelectedObject = Control就可以搞定,让PropertyGrid显示Control的所有属性.可是这里显示的属性名是英文的.对于我们开发人员来说这无可厚非,我们也乐于接受.并且让PropertyGrid显示中文属性名,这对于我们开发人员的使用来说显得多此一举.可是,对于我这种类型的一个应用工具,英文属性名对于很多客户来说可能就很难懂

润乾报表设计器中使用 spring 框架实现自定义数据集

spring是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.在 web 开发环境中经常会与 struts.hibernate联合起来使用,进行规范的框架结构开发.润乾中的二次开发也可以与 SSH 框架相结合部署到 web 项目中.本文介绍在设计时没有启动 web 服务,在设计器中使用 spring 的方式来实现自定义数据集. 实现思路:编写两个自定义数据集,一个在设计器中使用,一个在 web 项目中使用,在设计器中使用的类需要编写临时加载 spring 框架配置文件的代码,启动 spr

【StiReport】在设计器中增加自定义函数

1.创建一个自定义函数 namespace Winform { public class methos { public static string 小数转换成中文(decimal 小数) { return "321"; } } } 2.将函数注册到StiReport中 StiFunctions.AddFunction("自定义函数", "小数转换成中文", "小数转换成中文", "小数转换成中文", ty

C# 报表设计器 (winform 设计端)开发与实现生成网页的HTML报表 开放源码及调试

记得2010年之前,公司的项目基本上都要用到报表,以前我们常用的方法就是针对客户的需求来定制化开发(基本上是死写代码)来实现,经常导致项目经常性的延期,因为客户的需求经常会变化,随着用户的使用认知度的提高,对报表的要求越来越高,导致程序员不停的修改代码来实现,效率不高.结束遥遥无期...非常的痛苦:当然市面上有很多报表开发工具可以实现,但是针对小公司来说采购一套这样的系统的成本也非常的高,所以我们决定自己来开发一套像目前的润乾.FineReport 这样的报表设计器,来实现快速的报表设计制作.

窗体设计器出不来

今天发现个问题,C# WINFORM.如果在窗体类上写一些代码.那么双击FORM就出不来设计器了.FORM变成普通类了.去掉之后正常了 在form1窗体上面写了一个类A.结果图标变成C#类的.如果双击它,打开的是类,而不是窗体设计视图.按shift+F7也无效 去掉这些代码之后,正常了.双击打开设计视图了