首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >克隆TStringGrid组件

克隆TStringGrid组件
EN

Stack Overflow用户
提问于 2009-10-06 12:59:16
回答 4查看 5.2K关注 0票数 1

我开始学习Delphi了。因此,我决定从头开始编写一个类似MS Excel的应用程序。在新的Form1中,我确实放置了一个只包含1个页面的TPageControl组件。在该页面中,我确实放置了一个TAdvStringGrid和一个带有一些按钮(button1,button2)的TPanel和一个Popup1菜单,用于定义网格上的一些操作,如复制单元格、复制行、删除行等。对于该StringGrid,我还定义了一些属性,如颜色、字体等。我在主窗体中添加了一个带按钮的工具栏,以便向PageControl添加更多页面。该按钮的OnClick方法定义了两个操作:

1)在PageControl中添加新的Page2;2)在新建的StringGrid中添加新的Page2。

在Tpagecontrol的新页面中创建的新(运行时定义的) StringGrid应该继承(获取、复制、克隆、复制)在设计时已经在第一个页面中定义的StringGrid父元素的属性和方法,并且应该能够像调用StringGrid父元素一样调用PopUp1菜单。我们该怎么做呢?

一开始,我认为我应该只使用assing()复制StringGrid属性,但是当使用这种方法时,当鼠标右键单击新的StringGrid时,弹出菜单不会弹出……Form1的按钮(button1和button2)只适用于第一个StringGrid,而不适用于新添加的一个。我确实在某处读到为了解决这个问题,我可以通过使用写和读TMemoryStream来复制StringGrid组件(将父字符串网格保存到内存流中,创建一个新的字符串网格,然后将该内存流读取到新创建的字符串网格中),所以我这样做了,但是当程序执行这种组件克隆方法时,我得到了一个运行时错误。:-(

我确实仔细地检查了帮助。在这个话题上什么也没找到。似乎没有任何Delphi组件库或第三方组件来处理这类任务。有人能帮忙吗?:o)

EN

回答 4

Stack Overflow用户

发布于 2009-10-06 13:58:06

我会使用tabcontrol而不是pagecontrol。这样,您将得到多个选项卡,但只有一个页面和网格。然后,我将创建某种数据结构来保存所有的单元格信息,并将该结构呈现到网格中。这样,我就可以拥有多个结构,并让活动选项卡决定呈现哪个结构。你也会在你的gui和你的逻辑之间有一个更松散的耦合,使得以后的改变变得更容易。例如,如果您需要将来自不同电子表格的一些值引入到当前电子表格的单元格中,您可以加载一个结构并挑选出所需的值。根本不需要为第二个电子表格制作任何gui。

对于3.party组件,我推荐使用TMS FlexCell和TAdvSpreadGrid。这将为您提供所需的大部分内容。

票数 2
EN

Stack Overflow用户

发布于 2009-10-06 15:45:22

对于学习者来说,这是一个棘手的选择:)然而,你不需要开始流媒体。

查找TPersistent的assign()过程,这是您需要轻松复制网格部分的例程。例如

代码语言:javascript
复制
for i := 0 to StringGrid1.RowCount - 1 do
  StringGrid2.Rows[i].Assign(StringGrid1.Rows[i]);

为了简单起见,使用Tag属性区分网格(StringGrid1.Tag := 1,StringGrid2.Tag := 2等。

弹出菜单也非常简单:

然后你必须在StringGrid2.popupmenu := stringGrid1.popupMenu例程中决定哪个网格是“活动的”,比如l

代码语言:javascript
复制
Tform1.popupMenuItem1Click(Sender: TObject)
  if Sender is TStringGrid then
    Case TStrigngGrid(Sender).Tag of
     1: // Grid 1
     2: // Grid 2

您可以对按钮使用相同的简单逻辑。

正如neftali提到的,最好的方法是将创建的网格放在一个ObjectList中。然后,您将得到稍微复杂但可扩展的代码:

代码语言:javascript
复制
Tform1.popupMenuItem1Click(Sender: TObject)
 var AGrid: TStringGrid;

  if Sender is TStringGrid then
     AGrid := MyListOfStringGrids[MyListOfStringGrids.IndexOf(Sender)];
       DoMenuItem1Stuff(AGrid);

玩得开心

票数 1
EN

Stack Overflow用户

发布于 2009-10-06 13:05:37

亲爱的各位,我正在努力学习Delphi

Delphi风格是查找/创建/购买完成工作的组件,并在设计时使用它们。您可以尝试基于网格或使用TFrame创建自定义组件。查看Custom Component Development中的链接和随Delphi提供的帮助文件。

如果你真的需要动态克隆控件,我发现here就是一个使用stream.ReadComponent的例子。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1525429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档