1

私は Delphi を学び始めています。そこで、MS Excel のようなアプリケーションをゼロから作成することにしました。新しい Form1 に、1 ページのみを含む TPageControl コンポーネントを配置しました。そのページでは、TAdvStringGrid と、いくつかのボタン (button1、button2) を含む TPanel と、セルのコピー、行のコピー、行の削除など、グリッドでいくつかのアクションを定義するための Popup1 メニューを配置しました。その StringGrid についても、色、フォントなど、いくつかのプロパティを定義しました。PageControl にページを追加するために、ボタン付きのツールバーをメイン フォームに追加しました。そのボタンの OnClick メソッドは 2 つのアクションを定義します:
1) 新しい Page2 を PageControl に追加するため、および 2) 新しい StringGrid を新しく作成された Page2 に追加するため。

Tpagecontrol の新しい Page で作成された新しい (実行時に定義された) StringGrid は、設計時に最初のページで既に定義されている StringGrid 親のプロパティとメソッドを継承 (取得、コピー、複製、複製) し、呼び出すことができる必要があります。 StringGrid の親と同じように、PopUp1 メニュー。これをどのように行うのですか?

最初は、assing() を使用して StringGrid プロパティをコピーするだけでよいと考えていましたが、このアプローチを使用すると、新しい StringGrid を右クリックしてもポップアップ メニューが表示されず、ボタン (button1 と button2) が表示されません。 of Form1 は最初の StringGrid でのみ機能しますが、新しく追加されたものでは機能しません。この問題を解決するために、書き込みと読み取りの TMemoryStream を使用して StringGrid コンポーネントを複製できることをどこかで読みました (親 stringgrid をメモリストリームに保存し、新しい stringgrid を作成してから、そのメモリストリームを新しく作成された stringgrid に読み込みます)。そうしましたが、プログラムがこのコンポーネントのクローン作成メソッドを実行すると、ランタイム エラーが発生します。:-(

ヘルプを注意深くチェックしました。そのトピックには何も見つかりませんでした。この種のタスクに対処する Delphi コンポーネント ライブラリまたはサードパーティ コンポーネントはないようです。誰か助けてくれませんか?:o)

4

4 に答える 4

2

ページコントロールの代わりにタブコントロールを使用します。そうすると、複数のタブが作成されますが、ページとグリッドは1つだけになります。次に、すべてのセル情報を保持するためのある種のデータ構造を作成し、この構造をグリッドにレンダリングします。このようにして、複数の構造を持つことができ、アクティブなタブにレンダリングする構造を決定させることができます。また、GUIとロジックの間の結合が緩くなり、後で変更しやすくなります。たとえば、別のスプレッドシートから現在のスプレッドシートのセルにいくつかの値を取り込む必要がある場合は、構造をロードして、必要な値を選択できます。2番目のスプレッドシートのGUIを作成する必要はまったくありません。

3.partyコンポーネントの場合、TMSFlexCellとTAdvSpreadGridをお勧めします。それはあなたが必要とするもののほとんどをあなたに与えるでしょう。

于 2009-10-06T13:58:06.017 に答える
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 など) を使用してグリッドを区別します。

ポップアップ メニューも非常にシンプルです。

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 に配置するのが最善の方法です。その後、少し複雑ですが、expandabe になります。

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

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

楽しむ

于 2009-10-06T15:45:21.513 に答える
0

親愛なる皆さん、私は Delphi を学ぼうとしています

Delphi スタイルは、仕事をするコンポーネントを見つけ、作成し、購入し、設計時に使用することです。グリッドまたは使用に基づいてカスタム コンポーネントを作成してみることができますTFrameカスタム コンポーネント開発からのリンクと、Delphi に付属のヘルプ ファイルを参照してください。

コントロールを動的に複製する必要がある場合は、私が見つけたstream.ReadComponent.

于 2009-10-06T13:05:37.183 に答える
0

「...そして、Form1 のボタン (button1 と button2) は、最初の StringGrid でのみ機能しますが、新しく追加されたものでは機能しません。この問題を解決するためにどこかで読んだことがあります...」

これを解決する一般的な方法はありません。Delphi は、それを解決するためのさまざまなツールを提供しています。

  1. すべての StringGrid を含むオブジェクトのリスト (TObjectList) を作成できます。Button1 Click イベントでは、現在使用しているグリッドを検索する必要があります。例 (他のボタンの BIS):

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 を使用したくない場合は、代替手段があります。すべての StringGrid に Tag プロパティを使用できます。0、1、2、3、... を割り当てます。
インデックス(アクティブなページ)を抽出し、同じ値を持つプロパティ Tag を持つ TStringGrid を検索します。これはFindComponentで行うことができます。最初の方法の方が優れています。;-)

よろしく。PD: 下手な英語ですみません。

于 2009-10-06T14:25:46.383 に答える