克隆TStringGrid组件

时间:2009-10-06 12:59:16

标签: delphi properties components cloning

我开始学习德尔福。所以我决定从头开始编写像MS Excel这样的应用程序。在一个新的Form1中,我确实放了一个只包含1页的TPageControl组件。在那个页面中,我确实放了一个TAdvStringGrid和一个带有一些按钮的按钮(button1,button2)和一个Popup1菜单,用于定义网格上的一些动作,比如复制单元格,复制行,删除行等。对于那个StringGrid,也是,我已经定义了一些属性,比如颜色,字体等。我在主窗体中添加了一个带有按钮的工具栏,以便向PageControl添加更多页面。该按钮的OnClick方法定义了两个动作:
1)将新的Page2添加到PageControl,和 2)在新创建的Page2中添加一个新的StringGrid。

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

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

我仔细检查了帮助。没有找到该主题。似乎没有任何Delphi组件库或第三方组件可以应对这种任务。请帮忙吗? :O)

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

学习者的一个棘手的选择:)但是你不需要开始流式传输。

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

for i := 0 to StringGrid1.RowCount - 1 do
  StringGrid2.Rows[i].Assign(StringGrid1.Rows[i]);

轻松开始使用Tag属性区分您的网格(StringGrid1.Tag:= 1,StringGrid2.Tag:= 2 Etc。

弹出菜单也非常简单:

StringGrid2.popupmenu := stringGrid1.popupMenu然后你必须在弹出例程中决定哪个网格是“活跃的”某些东西我喜欢

Tform1.popupMenuItem1Click(Sender: TObject)
  if Sender is TStringGrid then
    Case TStrigngGrid(Sender).Tag of
     1: // Grid 1
     2: // Grid 2

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

正如neftali所说,最好的办法是将创建的网格放在ObjectList中。 然后你会得到稍微复杂但扩展的东西:

Tform1.popupMenuItem1Click(Sender: TObject)
 var AGrid: TStringGrid;

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

玩得开心

答案 2 :(得分:0)

  

亲爱的,我正在努力学习德尔福

Delphi风格是查找/创建/购买完成工作并在设计时使用它们的组件。您可以尝试根据网格制作自定义组件或使用TFrame。请参阅Custom Component Development中的链接以及Delphi附带的帮助文件。

如果您确实需要动态克隆控件,here是我发现使用stream.ReadComponent的示例。

答案 3 :(得分:0)

“...并且Form1的按钮(button1和button2)仅适用于第一个StringGrid,但不适用于新添加的。我确实读过某个地方,为了解决这个问题...”< / em>

没有解决此问题的通用方法。德尔福提供了不同的工具来解决它。

  1. 您可以创建一个包含所有StringGrid的对象列表(TObjectList);在Button1 Click事件中,您必须搜索此时正在使用的网格。例如(其他按钮的BIS):

  2. var  
      index:integer;  
      sg:TStringGrid;  
    begin  
      ...  
      // search the active page   
      index := pageControl.ActivePageIndex;    //0, 1, 2,...  
      // USe this for search the StringGrid  
      sg := TStringGrid(OList.Objects[index]);  
      // the code that you have at the event bus woking with sg 
      // not stringgrid1, stringgrid2,...
      ...
      sg.Color :=      
      ...
    

    如果您不想使用ObjectList,还有其他选择。您可以对所有StringGrids使用Tag属性。分配0,1,2,3,...
    提取索引(活动页面)并搜索具有相同值属性Tag的TStringGrid。您可以使用 FindComponent 执行此操作。第一种方法更好。 ; - )

    的问候。 P.D:我的英语不好的借口。