【问题标题】:Can't view designer when coding a form in C#在 C# 中编写表单时无法查看设计器
【发布时间】:2015-11-24 18:10:19
【问题描述】:

我正在关注 this 关于 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' 要么未声明,要么从未分配”。我可以选择“忽略并继续”,这会将我带到一个没有文本框的表单。

为什么会发生这种情况?我知道你们中的一些人认为我应该只使用工具箱,这可能是最明智的做法,但我仍然想了解为什么会发生这种情况。

【问题讨论】:

  • 您必须声明 txtbox 的类型。它在哪里?你不能指望设计师展示 InitializeComponent() 中发生的任何事情
  • 您是否使用了一些第三方控件?如果是,那么它会导致您面临这样的问题。
  • @Yogee 我在第一个文件中声明了txtbox的类型,我想既然类是部分的,它可以找到类型就好了。
  • @Lali 好的,但我只使用标准控件。

标签: c# .net winforms visual-studio windows-forms-designer


【解决方案1】:

当您在 Windows 窗体设计器中打开 Form 时,设计器会查看文件中的第一个类。如果文件有一个 Designer.cs 包含类的其他部分,也包括它并尝试反序列化这些文件内容。在反序列化和加载表单设计时的过程中,它会创建表单的基类 实例,并在这些文件中查找组件声明和InitializeComponents 方法。如果发现它们使用反序列化代码创建组件并设置它们的属性,并将组件添加到创建的基类实例中。

一些有用的事实:

  • Form 的构造函数中的代码不会在设计时执行,但表单基类的构造函数将在设计时执行。
  • InitializeComponent 中的代码不会在设计时执行,但这些代码将被反序列化并用于创建表单设计器。
  • 设计器无法显示具有抽象基类的表单。 (solution)
  • 设计器无法显示具有通用类的表单。例如它不能显示MyForm:SomeForm<SomeClass>,但它可以显示SomeForm<T>:Form。 (solution)
  • 如果您为表单定义新属性,这些属性将不会显示在属性窗口中。属性窗口,显示基类的属性,但包含表单的值。
  • 当文件包含 2 个类时,如果表单不是设计器无法加载的第一个类,并且您会收到一条警告,指出该表单应该是在设计器中显示的第一个类。
  • 上述规则也适用于 UserControls。

示例

看看下面的代码,它有一些严重的问题:

  • 类的构造函数与类名不同
  • 声明int i="x";
  • 这是一个 C# 类,没有分号
  • InitializeComponent 方法未在构造函数中调用

但有趣的是,即使有这些错误,您也可以在设计器中看到表单!

只需在您的项目中创建一个文件并将以下代码放入文件中并保存文件并关闭它。然后在不尝试构建解决方案的情况下,在设计器中打开表单。这是代码:

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
    }
}

这是设计师的截图:

更多信息

要了解更多信息,请查看此链接:

您的问题的解决方案

作为一种解决方案,您只需移动 private Numeric txtbox; 并将其放在您的第二个文件中即可 Exercise 类。

【讨论】:

  • 非常感谢!这对我来说有点道理。我的以下理解是否正确?当我要求 VS 显示表单时,它不会编译任何东西;它只解析和反序列化(这似乎意味着将代码转换为字节),因此即使我的类是部分的,它也不看类的另一半?课程的另一半是我初始化“txtbox”的地方,但它没有看到这个。如果我把所有东西都放在同一个(非部分)类中,我应该对设计器没有问题。
  • 是的,您非常了解幕后发生的事情。设计者以某种方式(使用 CodeDom 序列化程序)解析并将您编写的代码转换为内存中的控件实例,并将它们添加到您的基类实例中并在设计图面上显示它们。
【解决方案2】:

控件的声明应该放在 Designer.cs 文件中,以便 Visual Studio 可以编译这个单元并显示它。

当您启动应用程序时,编译器会考虑您的部分类的所有部分,然后它会找到 txtBox 声明。

尝试仅将带有图形声明的表单类保留在单个文件中。 这个单一文件应该有在 InitializeComponent() 中初始化的 UI 组件的 InitializeComponent 方法、构造函数和字段声明。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多