winforms 为什么Visual C++ Designer在我向窗体中添加控件后不工作?

qgzx9mmu  于 2023-05-07  发布在  其他
关注(0)|答案(5)|浏览(189)

我想在面板中打开双缓冲,但唯一能打开DoubleBuffered属性的方法是创建一个继承自System::Windows::Form::Panel的新类,如下所示:

#include "stdafx.h"

public ref class CPPIConfig: public System::Windows::Forms::Panel
{
public: CPPIConfig()
        {
            this->DoubleBuffered = true;
        }
};

现在我们的表单看起来像这样:

#pragma once
#using <system.drawing.dll>
#include "CPPIConfig.h"

[...]

public ref class C3_User_Interface : public System::Windows::Forms::Form
    {
      [...]
      public: CPPIConfig^ pPPI;
      [...]
    }

void InitializeComponent(void)
    {
        [...]
        this->pPPI = (gcnew CPPIConfig());
        [...]
    }
[...]

它的建立和运行,没有问题。但是,当我现在尝试在设计模式下查看表单时,出现以下错误:

**C++ CodeDOM解析器错误:行:144,列:15 ---未知类型'CPPIConfig'。**请确保引用了包含此类型的程序集。如果此类型是开发项目的一部分,请确保已成功生成该项目。

我的问题:
1.为什么设计模式不起作用,即使代码构建并运行?我已经尝试了几个干净的构建,但这似乎不是问题所在。
1.有没有一种方法可以不使用此方法将DoubleBuffered设置为true

o2gm4chl

o2gm4chl1#

这里的大障碍实际上源于我对托管与非托管代码。我去了MSDN to read more about it,但结果是这样的:Visual Studio无法在此上下文中处理我的CPPIConfig类,因为它是非托管/本机代码。
根据为similar question提供的答案:
Windows窗体设计器无法反映混合模式的EXE。确保使用/clr:pure编译或移动任何需要设计时支持的类(例如窗体上的组件和控件)添加到类库项目中。
反射(as this MSDN page points out)是“设计”视图在IDE中用于呈现窗体的内容。简而言之,这就是反思:
反射允许在运行时检查已知的数据类型。反射允许枚举给定程序集中的数据类型,并且可以发现给定类或值类型的成员。无论该类型在编译时是已知的还是被引用的,都是如此。这使得反射成为开发和代码管理工具的有用特性。
啊。这就说得通了。
据我所知,有两种方法可以解决这个问题。

**在项目属性中使用/clr:pure。**这将更改项目的公共语言运行时支持。关于this MSDN page:

纯程序集(用/clr:pure编译)可以包含本机和托管数据类型,但只能包含托管函数。与混合程序集一样,纯程序集允许通过P/Invoke与本机DLL进行互操作(请参见在C中使用显式PInvoke(DllImport Attribute)),但C互操作功能不可用。此外,纯程序集不能导出可从本机函数调用的函数,因为纯程序集中的入口点使用__clrcall调用约定。

**创建一个类库项目。**正如另一个答案所建议的,如果我将文件移动到类库项目并以这种方式引用它,我就不会看到这个问题。据我所知,它将使CPPIConfig托管代码。

最终,结构上的限制使得这两种选择都不可行,为了节省时间,我们决定暂时放弃面板上的双缓冲。至少我对这个环境了解得更多了!

sbtkgmzw

sbtkgmzw2#

尝试将正在初始化的控件移动到suspendlayout下方。这允许设计器正确呈现而不会出现CodeDOM解析错误。
原创是这样的

#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
    this->lblMessage = (gcnew System::Windows::Forms::Label());
    this->SuspendLayout();
    // lblMessage
    this->lblMessage->Location = System::Drawing::Point(12, 230);
    //.....
}

新格式

#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
    this->SuspendLayout();
    // lblMessage
    this->lblMessage = (gcnew System::Windows::Forms::Label());
    this->lblMessage->Location = System::Drawing::Point(12, 230);
    //.....
}
cyej8jka

cyej8jka4#

我也从Panel继承了一个类。在我的例子中,我已经将这个工具箱项放置在它自己的C#项目中,并具有自己的名称空间。由于未知的原因,设计器在第一次实现时工作,然后在我试图在第二个文件中使用继承的类时中断。
为了解决这个问题,我更改了C#项目的命名空间,以匹配消费项目的命名空间,并在设计器代码中显式指定它:
Project1::InheritedPanel^
而不是简单地
InheritedPanel^

cxfofazt

cxfofazt5#

下面是我遇到的“C++ CodeDOM解析器错误:...”问题。
突然,我的VS 2019拒绝为我的Form1.h加载设计器。我得到了和上面一样的消息。一年前,没有任何问题,但现在我想继续工作。
令人惊讶的原因是,在过去,我移动了太多的功能到另一个源文件!因为我不想让Form1.h太大,所以我替换了

void Form1::foo()
{
}

通过

void foo();

并创建了一个foo.cpp

#include "Form1.h"
void Form1::foo()
{
}

现在这不再起作用了!一个或两个外部功能是可以的,但超过三个会导致所描述的效果。
所以我把所有东西都放回Form1.h,问题就解决了。

相关问题