WinForm设计时异常】关于VS.NET中窗体设计器初始化控件引发的设计时异常

 
在用 VS.NET进行窗体设计的时候,经常会遇到这样的问题:我们需要在构造函数或者在OnLoad事件中进行自己的一些初始化操作,比如连接一个数据库、调用一个资源文件或者后期绑定一个组件。如果代码通过编译,在运行时会执行得相当如你所愿。然而,当我们用窗体设计器打开这样一个窗体或者继承的窗体,IDE环境会抛出非常令人不愉快的异常,比如(NullReferenceException )。
究其原因,主要是窗体设计器在载入窗体时会自动初始化该对象,自动执行诸如构造函数、 OnLoad 方法和 InitializeComponent 方法,目的在于能使窗体设计器展现出可视化的编辑操作环境。(一些第三方控件也就是利用这个时机弹出注册认证的)。
现在大家明白了,原来我们通过窗体设计器打开一个窗体类或控件类时, IDE 环境已经悄悄地在宿主进程中实例化了我们的类。
如果我们在构造函数中写了这样的代码:
  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.  
  9.          //… 
问题便由此产生, fileName 参数的值是程序在运行时传递的,设计时当然无从获得。所以,窗体设计器在打开此窗体类时,必然会抛出异常,同时窗体将无法正常显示。
解决这种问题的办法网上其他朋友说了很多,归纳起来好像主要有以下三种途径:
一、判断 this.DesignMode 属性
这是让人一眼看过去就觉得最直接最有效的方法,绝对有一种踏破铁蹄无觅处,得来全不费功夫的欣快感——可惜的是,用起来一点不奏效。因为如果该窗体是个独立窗体或控件,那一点问题都没有, DesignMode 的值如你所愿为 true ,但是如果它是包含在其他控件中被拖拽到设计器中(例如,把设计好的控件拖入新的 WinForms 窗体),那么那个接受拖拽的窗体才处于设计模式,而它不是,它已鬼使神差地进入了 RunTime 模式,然后如我所愿,抛出异常 J
二、利用 Assembly.GetEntryAssembly()方法
判断执行程序入口的组件是不是我们预想的,如果不是,那么必然是 IDE 的窗体设计器调用的——问题解决——只是有点大炮打蚊子的感觉。
三、定义一个静态成员,指示程序所处的模式
此方法我认为最好。具体做法是写一个全局类,也就是构造函数为 private 限制 的类,里面的成员都为 static 静态类型。这样的一个类由于构造函数是私有的,所以不可能自任何地方任何外部代码中实例化,从而保证了其内成员的唯一性。然后,在程序的入口处,把此类的一个用于表示运行模式的静态成员标识为“运行时”,下面 …. 一切都好说了,看代码吧:
  1. //全局类 
  2. public class GlobalClass 
  3. //私有构造器,防止实例化 
  4. private GlobalClass(){} 
  5. //用于标识运行时/设计时的bool型静态成员,初始值设为false 
  6. public static bool RunTimeMode = false
  7.   
  8. //包含程序入口的类 
  9. Public class Entry 
  10. … 
  11. //主线程入口点,窗体设计器绝不会执行此方法 
  12. static void Main(string[] args) 
  13.          //置为true 
  14. GlobalClass.RunTimeMode = true
  15. //….. 
  16.          } 
  17.          //… 
  18.   
  19. //某个窗体类 
  20. public class MyForm : System.Windows.Forms.Form 
  21.          public MyForm() 
  22.          { 
  23.                    //窗体设计器必须调用的 
  24.                    InitializeComponent(); 
  25.                    //判断运行模式 
  26.                    If( GlobalClass.RunTimeMode ) 
  27.                    { 
  28.                             //在此处做一些窗体设计器会报错的事情 
  29.                    } 
  30.                    //… 
  31.          } 
  32.          //… 
呵呵,问题圆满解决。其实这样一个全局类在我们平时设计系统的时候会经常用到,多用于存储一些对象间的交互数据或者运行时环境参数。
如果大家有什么更好的办法解决所述问题,记得分享哦 :)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在C# WinForm窗体,如果你想要在表格控件上填充颜色,但是鼠标经过其他控件整个表格里的数据都变了,可能是因为你在窗体上直接绘制了表格,而没有使用自定义控件来解决这个问题。\[1\] 你可以尝试使用自适应类来解决这个问题。首先,将自适应类的代码复制到你的工程命名空间,然后声明自适应类的实例。接下来,在窗体上添加SizeChanged事件,并在事件方法记录窗体控件的初始位置和大小。最后,调用自适应类的自适应方法,完成自适应。这样,你就可以在表格控件上填充颜色而不会受到其他控件的影响了。\[2\] 你还可以使用Panel、DataGridView等控件来实现自适应。\[2\] 在窗体的代码,你需要引入System、System.Collections.Generic、System.ComponentModel、System.Drawing和System.Windows.Forms这些命名空间,并在窗体的Load事件调用自适应类的初始化方法,记录窗体控件的初始位置和大小。然后,在窗体的SizeChanged事件调用自适应类的自适应方法,完成自适应。\[3\] 这样,你就可以在C# WinForm窗体使用表格控件,并且实现自适应的效果了。 #### 引用[.reference_title] - *1* [C#自定义控件实现窗体绘制表格](https://blog.csdn.net/qq_22955427/article/details/76252582)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [C# WinForm 窗体及其控件的自适应](https://blog.csdn.net/chbxgbin/article/details/109690260)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值