【问题标题】:Winform Custom Controls - Designer randomly stops initializing / calling constructorWinform 自定义控件 - 设计器随机停止初始化/调用构造函数
【发布时间】:2012-04-29 06:32:23
【问题描述】:

这是一场可怕的噩梦,我迫切需要帮助。我到处寻求帮助 没有什么可以作为永久修复。

我已经开发了一些自定义控件;扩展按钮、用户控件等的控件。我有一个问题,VS2010 不断随机地,没有我能辨别的押韵或理由,决定何时尝试打开使用它的自定义控件的控件的设计视图 (编辑:'它'是 Windows 窗体生成器) 应该完全删除从 .designer.cs 文件中调用自定义控件的构造函数的行,从而完全破坏我查看设计视图的能力。该应用程序仍然可以正常构建和运行。

我已经测试并排除了以下问题:

  1. 公共构造函数 - 显然具有非公共(内部等)构造函数可能会导致此类问题。我检查了 100 次 - 所有自定义控件都有公共构造函数。

  2. 空构造函数 - 除了是公共的,它还需要是空的。

  3. 不调用任何可能在构造函数中失败的东西 - 我已将自定义控件的所有构造函数减少为空

     Name() { }
    来电。运气不好。
  4. 命名空间 - 显然位于不同的命名空间会导致问题?我在同一个项目中,文件在同一个项目中。

  5. 卸载项目。关闭VS。删除 .suo 智能感知文件。删除 obj 文件。打开VS。重新加载项目。重建项目。还是没有运气。

这真是令人沮丧。到了这一点,我已经准备好放弃使用自定义控件并手动对每个控件进行蒙皮以避免它。有没有人知道是什么原因造成的?

【问题讨论】:

  • 一些可能没用的想法:你安装了最新的 VS2010 服务包吗?您的空公共构造函数是否在调用 : base() (不确定是否有必要)。如果您创建一个全新的空白 UserControl,会发生这种情况吗?
  • 您需要寻找被诊断吞没的异常。启动另一个 VS 实例并使用 Tools + Attach to Process 附加到第一个实例。调试 + 异常,勾选 CLR 异常的抛出框。回到第一个实例并开始设计。
  • 并仔细检查您的 SO 用户名如何影响您的代码。
  • 设计器文件明确警告您不要做您所做的事情。你很惊讶它出错了吗?
  • @TomW - 我在我的问题中说 - 我没有编辑 .designer.cs,文件中缺少构造函数调用是问题的症状。

标签: c# winforms visual-studio visual-studio-2010 custom-controls


【解决方案1】:

首先,问题...您将内容放入“.designer.cs”代码中...不要。那是微软的沙盒。创建 WinForms 表单和可视控件时,它们通常位于“集合”中,例如

MyForm.cs   (place for YOUR code)
   MyForm.designer.cs  (Microsoft's sandbox area for designer stuff)
   MyForm.resx   (Resource file -- if used, specific to this form).

也就是说,如果您通过普通的“设计器”打开您的 WinForm,然后右键单击“查看代码”,它将调出 MyForm.cs 代码集。注意它的一个

PARTIAL PUBLIC CLASS MyForm : Window
{
   public MyForm()
   {
      InitializeComponent();
   }
}

“MyForm.Designer.cs”和“MyForm.cs”基本上作为一个团队工作。你的东西除了微软的东西。根据您要执行的操作,您可以在此构造函数中将其挂钩以获取整体表单。如果您需要准备一些数据连接、查询数据、填充列表或将在表单中使用的任何内容。您可以通过多种方式进行(之前或之后)。

   public MyForm()
   {
      DoYourStuff();
      InitializeComponent();
      // or DoYourStuff here after designer controls are all initialized.
   }

   private void DoYourStuff()
   {  put it here }

有时您可能想在整个表单加载完成之后,但在最终呈现给用户之前做一些事情。有时,我实际上在整个表单(表单及其所有控件)的 LOADED 完成后放置了一个钩子。所以我做了类似的事情:

public MyForm()
{

   Load += MyAfterInitializeComponents;
   InitializeComponent();
}


private void MyAfterInitializeComponents(object sender, EventArgs e)
{  
   DoYourStuff(); 
}

如果您正在尝试做一些特定的事情,也许可以使用一些示例代码来帮助您集成到您的基于窗口的代码沙箱中。

【讨论】:

  • 正如我在问题中所说,我修改 .designer.cs 文件 - Designer.cs 文件正在修改 ITSELF 以不调用我的自定义控件的构造函数这使控件无法显示。我会在我的代码上测试你的解决方案——结果我遇到的问题是一个被覆盖的 OnLoad 函数,它有一个导致问题的 DoStuff()——我认为 OnLoad 只发生在运行时;解决方案是将 DoStuff 放入 if(!DesignMode) 中。添加到 Load 的函数是否仅在 !DesignMode 中调用?
  • @trycatch... 你现在好吗?你的评论有点不清楚。我使用 += 事件处理程序的钩子对我想要运行的 += 钩子执行正常的 IN ADDITION(根据我的示例)。
  • 我目前正在使用 if(!DesignMode) 来包围我正在崩溃的代码;这可行,但感觉很草率。所以我肯定会稍后再试一试你的 Load += Foo() 。我正在使用覆盖 OnLoad(),显然,当您这样做并在设计视图中打开表单时,会调用 OnLoad。我必须测试 Load+= 是否在 DesignMode 中不执行。
  • 好吧,我收回;这两种方法都不是完全有效的。我又控制了。我添加了一个 try/catch,我正在尝试将控件添加到一个新对话框中 - 我正在打印堆栈跟踪,无论我使用哪种方式,它都绝对会进入我的初始化代码。使用 if !DesignMode,它说 DesignMode.ToString() 在我的堆栈跟踪中为 false .. 使用 Load += 它也会进入代码。这世界到底是怎么回事??整个项目的其他任何地方都没有引用这个函数。
  • 另外值得一提的是,我可以在它的设计模式下查看控件就好了...?
猜你喜欢
  • 1970-01-01
  • 2017-10-09
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-30
  • 2013-11-17
相关资源
最近更新 更多