2

我想在面板中打开双缓冲,但我们可以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. 为什么设计模式不起作用,即使代码构建并运行?我已经尝试了几个干净的构建,但这看起来不是问题。
  2. 有没有一种方法可以DoubleBufferedtrue不使用此方法的情况下进行设置?
4

4 回答 4

5

这里最大的问题实际上源于我对托管代码和非托管代码的混合。我去MSDN 阅读更多关于它的信息,但结果是:Visual Studio 无法CPPIConfig在此上下文中处理我的类,因为它是非托管/本机代码。

从为类似问题提供的答案中:

Windows 窗体设计器无法反映混合模式 EXE。确保使用 /clr:pure 编译或将任何需要设计时支持的类(例如表单上的组件和控件)移动到类库项目中。

正如此 MSDN 页面所指出的,反射是设计视图用于在 IDE 中呈现表单的内容。简而言之,这就是反射:

反射允许在运行时检查已知的数据类型。反射允许枚举给定程序集中的数据类型,并且可以发现给定类或值类型的成员。无论该类型在编译时是否已知或引用,这都是正确的。这使得反射成为开发和代码管理工具的有用功能。

啊。这开始有意义了。

据我所知,有两种方法可以解决这个问题。

/clr:pure在您的项目属性中使用。这会更改项目的公共语言运行时支持。从这个 MSDN 页面:

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

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

最终,结构限制使这些选项都不可行,并且为了时间的利益,我们决定暂时放弃面板上的双缓冲。哦,好吧,至少我对这个环境有了更多的了解!

于 2012-06-01T20:58:29.963 回答
1

尝试将控件初始化移动到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);
    //.....
}
于 2014-10-16T15:34:59.613 回答
0

我也有一个从 Panel 继承的类。就我而言,我已将此工具箱项放置在其自己的 C# 项目中,并具有自己的命名空间。由于未知的原因,设计者在第一次实现时工作,然后在我尝试在第二个文件中使用继承的类后中断。

为了修复它,我更改了 C# 项目的命名空间以匹配使用项目的命名空间,并在设计器代码中明确指定它:

Project1::InheritedPanel^

而不是简单地

InheritedPanel^

于 2022-01-26T00:28:20.037 回答