在C#中编写表单时无法查看设计器
我正在关注winforms的这个教程,到目前为止,教程正在编写表单而不使用工具箱。 我相信它很快就会更深入地介绍工具箱。
在本教程之后,我在以下两段代码中进行了部分类:
第一档 :
using System; using System.Windows.Forms; public class Numeric : System.Windows.Forms.TextBox { public Numeric() { } } public partial class Exercise { private Numeric txtbox; System.ComponentModel.Container components; }
第二档 :
using System; using System.Windows.Forms; public partial class Exercise : Form { private void InitializeComponent() { txtbox = new Numeric(); Controls.Add(txtbox); } public Exercise() { InitializeComponent(); } } public class program { public static int Main() { Application.Run(new Exercise()); return 0; } }
当我使用F5运行代码时,一切看起来都很好:表单弹出文本框。
但出于某种原因,当我右键单击第二个文件并选择“视图设计器”时,我收到一条错误,上面写着“变量’txtbox’未声明或从未分配过”。 我可以选择“忽略并继续”,这会将我引导到一个没有文本框的表单。
为什么会这样? 我知道有些人认为我应该使用工具箱,这可能是最明智的做法,但我仍然想知道为什么会这样。
在Windows窗体设计器中打开Form
时,设计器会查看文件中的第一个类。 如果文件具有包含该类的其他部分部分的Designer.cs
,则还包括它并尝试反序列化这些文件内容。 在反序列化和加载表单设计时的过程中,它会创建表单基类的实例,并在这些文件中查找组件声明和InitializeComponents
方法。 如果找到它们使用反序列化代码创建组件并设置它们的属性,并将组件添加到创建的基类实例。
一些有用的事实:
-
Form
构造函数中的代码不会在设计时执行,但表单基类的构造函数将在设计时执行。 -
InitializeComponent
代码不会在设计时执行,但这些代码将被反序列化,并将用于创建表单的设计者。 - 设计者无法显示具有抽象基类的表单。 ( 解决方案 )
- 设计者无法显示具有generics类的表单。 例如,它无法显示
MyForm:SomeForm
,但它可以显示SomeForm
。 ( 解决方案 ):Form - 如果为表单定义新属性,则属性将不会显示在属性窗口中。 属性窗口显示基类的属性,但包含表单的值。
- 当一个文件包含2个类时,如果表单不是设计者无法加载的第一个类,则会收到一条警告,指出该表单应该是第一个在设计器中显示的类。
- 以上规则也适用于UserControls。
例
看看下面的代码,它有一些严重的问题:
- 该类具有与类名不同的构造函数
- 语句
int i="x";
- 没有分号,而这是一个C#类
-
InitializeComponent
方法未在构造函数中调用
但有趣的消息是你可以在设计师中看到这个forms,即使有这些错误!
只需在项目中创建一个文件,并将下面的代码放在文件中,然后保存文件并关闭它。 然后在不尝试构建解决方案的情况下,在设计器中打开表单。 这是代码:
using System using System.Windows.Forms namespace SampleApplication { public class MyForm:Form { public NotMyForm() { } public void InitializeComponent() { int i="x"; textBox1 = new TextBox() textBox1.Text = "Hi" this.Controls.Add(textBox1) } private TextBox textBox1 } }
这是设计师的截图:
更多信息
要查找更多信息,请查看以下链接:
- Visual Studio中的Windows窗体设计器如何加载窗体?
解决您的问题
作为一种解决方案,您可以移动private Numeric txtbox;
并将它放在Exercise
课中的第二个文件中。
控件的声明应放入Designer.cs文件中,以便Visual Studio可以编译该单元并显示它。
当您启动应用程序时,编译器会考虑您的部分类的所有部分,然后它会找到txtBox声明。
尝试只将表单类及其图形声明留在一个文件中。 这个单个文件应该具有在InitializeComponent()中初始化的UI组件的InitializeComponent方法,构造函数和字段声明。