喫茶XRAYトップページ


[5872] FMXなStringGrid返信 削除
2012/3/12 (月) 16:52:51 Syake
DEKOさんのところで、TStringGridで文字列の描画位置に関するサンプルが出て
おります。
http://ht-deko.minim.ne.jp/techf011.html
大変参考になります。

様々工夫のあるとこではありますが、私的には・・・・
//-----------------------------------------------------------//
procedure TForm1.StringGrid1Paint(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
var
  i,j :Integer;
begin
  with (Sender as TStringGrid) do
  begin
    for i := 0 to ColumnCount-1 do
    begin
      for j := 0 to RowCount-1 do
      begin
        if Assigned(TTextCell(StringGrid1.Columns[i].CellControlByRow(j))) then
        begin
          with TTextCell(StringGrid1.Columns[i].CellControlByRow(j)) do
          begin
            if (i mod 2 = 0) and (j mod 2 = 0) then
            begin
              TextAlign := TTextAlign.taCenter;
            end else begin
              TextAlign := TTextAlign.taLeading;
            end;
          end;
        end;
      end;
    end;
  end;
end;
//--------------------------------------------------------//
の方が良いような気がしました。

動的に変更しやすのでは・・・ないか・・・と。
釈迦に説法です。m(_ _)m


ところで、TStringGridの子コントロールにTPlotGridを追加すると
大変面白いことになります。
procedure TForm1.Button1Click(Sender: TObject);
var
  Col, Row: Integer;
begin
  StringGrid1.BeginUpdate;
  for Col := 0 to StringGrid1.ColumnCount-1 do
  begin
    for Row := 0 to StringGrid1.RowCount-1 do
    begin
      StringGrid1.Cells[Col, Row] := 'Cell[' +
        IntToStr(Col) + ',' + IntToStr(Row) + ']';
    end;
  end;
  StringGrid1.EndUpdate;
end;
こんなんで、確認できます。

実のところ・・・

StringGridで遊んでいたら、ある時表示が妙におかしいことに
気がつきました。
ちょっと土ツボにはまってました。(^_^;)
ふと見ると、StringGridの子コントロールにTPlotGridがいつの
間にやら(って、自分がやったんじゃろ)追加されていて、はず
したら上手く(元に戻った)いったという落ちですけど...。

もっとも、こんな事する人いないでしょうが...。



[5873] Re:FMXなStringGrid返信 削除
2012/3/12 (月) 17:23:07 Syake
続いて、Colmunの削除です。

procedure TForm1.Button2Click(Sender: TObject);
begin
  {Colを削除する}
  if StringGrid1.ColumnCount > 2 then
  begin
    //StringGrid1.BeginUpdate;
    StringGrid1.Columns[StringGrid1.ColumnCount-2].Release;
    //StringGrid1.EndUpdate;
    //StringGrid1.Repaint;
    //StringGrid1.Visible := False;
    //StringGrid1.Visible := True;
  end;
end;

削除できました。

ところが、StringGridのOnPaintが実行されません。

RePaintはダメでした。
BeginUpDate,EndUpDateもダメです。
(描画停止と開始と解釈した私がいけないの?)
強引に
Visible False→True もダメです。

もっとも、StringGridをスクロールするか、フォームを
一旦隠して再描画するとOnPaintが実行されるようです。
(それじゃ、だめじゃん)

さてさて、どうしたもんかいな。

[5874] Re2:FMXなStringGrid返信 削除
2012/3/12 (月) 17:35:03 Syake
忘れてた、Gridの作成

procedure TForm1.Button4Click(Sender: TObject);
var
  i :Integer;
begin
  with StringGrid1 do
  begin
    RowCount := 20;
    for i := 0 to 7 do
    begin
      AddObject(TStringColumn.Create(StringGrid1));
      Columns[i].Width := 100;
      (Columns[i] as TColumn).Header := 'Title' + IntToStr((Columns[i] as TColumn).Index);
      (Columns[i] as TStringColumn).ReadOnly := True;
    end;
    ShowHeader := False;    //  ヘッダーを表示するか
    ShowVertLines := False; //  Cellの境界縦線を描画するか(True,False)
    //ShowHorzLines     Cellの境界横線を描画するか(True,False)
    //ShowScrollBars   スクロールバーを表示するか
    //ShowSelectedCell  アクチブなCellを白抜き表示するか(True,False)
  end;
end;

まあ、こんな感じでよろしいのでしょうか?

DEKOサンの所にあった、枠のオリジナル描画
http://blogs.embarcadero.com/teamj/2011/11/14/2598/
参考になります。

ただ、これは決め打ちなのでデータによっての描画は無理なようだと私的には
解釈しました。
なので、これからも試行錯誤が続きそうです。

[5876] Re:FMXなStringGrid返信 削除
2012/3/12 (月) 19:00:29 Mr.XRAY
▼ Syakeさん

Delphi XE2はまだ,IDEを整備,整えていないんです.実は.
だって,頻繁にUPDATEがあるので,何か不安なもんですから.
UP4を入れたので,試してみました.
ふ〜ん,これがTStringGrid.中々いい感じです.

> ところで、TStringGridの子コントロールにTPlotGridを追加すると
> 大変面白いことになります。


ハハッ.デザイン感覚はともかく,このTPlotGridって使えそうです.

> もっとも、こんな事する人いないでしょうが...。

多分....

>http://blogs.embarcadero.com/teamj/2011/11/14/2598/
>参考になります。


ですが,コードが画像なので,やる気起こりません.


[5878] Re2:FMXなStringGrid返信 削除
2012/3/12 (月) 19:17:02 Syake
▼ Mr.XRAYさん
> ですが,コードが画像なので,やる気起こりません.

そんなマスターのために

TStringColumn = class(FMX.Grid.TStringColumn)
  protected
    function CreateCellControl: TStyledControl; override;
  private
    procedure OnCellPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
  end;


function TStringColumn.CreateCellControl: TStyledControl;
var
  TxtCell :TTextCell;
begin
  Result := inherited;

  TxtCell := Result as TTextCell;
  TxtCell.OnPaint := OnCellPaint;
end;

procedure TStringColumn.OnCellPaint(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
begin
  if Sender is TTextCell then
  begin
    with Canvas do
    begin
      Stroke.Kind := TBrushKind.bkSolid;
      Stroke.Color := claRed;
      StrokeThickness := 1;
      DrawRect(ARect,0,0,AllCorners,1,TCornerType.ctRound);
    end;
  end;
end;

ちなみに
StringColmun1:TStringColmun; の記述は不要です。

こんなことじゃない!?




[5879] Re3:FMXなStringGrid返信 削除
2012/3/12 (月) 19:21:08 Syake
> ▼ Mr.XRAYさん
> > ですが,コードが画像なので,やる気起こりません.
>
> そんなマスターのために


忘れてました。

Gridの作成
のコードを実行すると上記の内容が描画されます。


procedure TForm1.Button1Click(Sender: TObject);
var
  i :Integer;
begin
  with StringGrid1 do
  begin
    RowCount := 20;
    for i := 0 to 7 do
    begin
      AddObject(TStringColumn.Create(StringGrid1));
      Columns[i].Width := 100;
      (Columns[i] as TColumn).Header := 'Title' + IntToStr((Columns[i] as TColumn).Index);
      (Columns[i] as TStringColumn).ReadOnly := True;
    end;
    ShowHeader := False;    //  ヘッダーを表示するか
    ShowVertLines := False; //  Cellの境界縦線を描画するか(True,False)
    //ShowHorzLines     Cellの境界横線を描画するか(True,False)
    //ShowScrollBars   スクロールバーを表示するか
    //ShowSelectedCell  アクチブなCellを白抜き表示するか(True,False)
  end;
end;


・・・多分

[5881] Re4:FMXなStringGrid返信 削除
2012/3/12 (月) 21:56:01 Mr.XRAY
▼ Syakeさん

FMXなTStringGird,表示できました.
単にコピペしただけですが.
ん? 横スクロールバーが...


[5882] Re5:FMXなStringGrid返信 削除
2012/3/12 (月) 22:04:17 Mr.XRAY
これが実行開始時の状態です.
前のはボタンクリックした時です.


[5883] Re6:FMXなStringGrid返信 削除
2012/3/13 (火) 07:36:13 yoshida
便乗して・・

VCLのOnSelectCellイベントでCellのRectが欲しいようなケースなんですが、
TStringColumn.OnEnterで、LocalRectあたりに期待したけれどダメっぽくて、
かろうじてAbsoluteRectあたりで計算してできるっぽいという感じですかね。

procedure TForm1.FColEnter(Sender: TObject);
begin
 Label1.Text := 'ColEnter:' + inttostr(trunc(TControl(Sender).AbsoluteRect.left)) + ' ' +inttostr(trunc(TControl(Sender).AbsoluteRect.top));
 //Label1.Text := 'ColEnter: ' + inttostr(trunc(TControl(Sender).ClipRect.left)) + ' ' +inttostr(trunc(TControl(Sender).ClipRect.top));
 //Label1.Text := ColEnter: ' + inttostr(trunc(TControl(Sender).LocalRect.left)) + ' ' +inttostr(trunc(TControl(Sender).LocalRect.top));
end;

OnEnterがまだ本気そうじゃないので、クリアしても壁はありますが(あきらめ感)



[5885] Re7:FMXなStringGrid返信 削除
2012/3/13 (火) 08:27:17 Syake
▼ yoshidaさん

> VCLのOnSelectCellイベントでCellのRectが欲しいようなケースなんですが、

私もCellRectを捕まえたいのですが、上手くいきませんっていうか良くわから
ないです。
参考にさせてください。

[5892] Re8:FMXなStringGrid返信 削除
2012/3/13 (火) 19:26:47 yoshida
▼ Syakeさん

> 私もCellRectを捕まえたいのですが、上手くいきませんっていうか良くわから
> ないです。


こちらは、VCLのInplaceEditorなんかもずーとしょぼいので、
マウス/カーソル位置にTEditなど編集コントロールを追従して表示するよう試行しています。
そんな感じでしょうか。
時間があったのでちょっと試しました。

TEditで追従するようにOnSelChanged、Edit1にOnExitを設定します。

procedure TForm1.StringGrid1SelChanged(Sender: TObject);
begin
  with StringGrid1 do          //Selected
  begin
    if Columns[ColumnIndex] = Nil then exit; //ColCount = 1 は無視

    Edit1.Position.X := Columns[ColumnIndex].AbsoluteRect.Left; //AbsoluteRectが適切かわからない
    Edit1.Position.Y := Position.Y + (Selected +1 - TopRow) * RowHeight; //Selected は,Row値
    Edit1.Width := Columns[ColumnIndex].AbsoluteRect.Width;
    Edit1.Text := Cells[ColumnIndex,Selected];
    Edit1.SetFocus;
  end;
end;

procedure TForm1.Edit1Exit(Sender: TObject);
begin
  with StringGrid1 do
  begin
    Cells[ColumnIndex,Selected]  := Edit1.Text;
    Edit1.Text := '';
  end;
end;

キー操作など細かい動きは別にしてWin32/MacともほぼOK、
ただ、スクロールでEdit1の位置が反映されません。
このあたりは、スクロール後、GridのUpdateSelectionする手段がないようで、
FMX.Gridソースを修正する必要がありました。
(ソースコピーしてユニット/クラス名変更もアリですが、他の方法ありましたっけ?)
ただし、なぜかMacターゲットの場合はコンパイルエラーがでます(注意&先行不安)

HScrollChange/VScrollChangeのUpdateSelectionの後にOnScrollBarChangeを追加し、
スクロール後、以下で再配置。

procedure TForm1.StringGrid1ScrollBarChange(Sender: TObject);
begin
     StringGrid1SelChanged(Nil);
end;

横スクロールはOKのようですが、
縦は、微妙に位置がずれるので、Y位置の微調整は必要そう。

といったところです。

#しかし、素性が違うモノを強引に同じStringGridとして販売するのはいかがなものかと。
#オブジェクト指向な開発ツール的に(笑)
#いつのまにか閉まっていますね。
http://www.ksdev.com/


[5898] Re9:FMXなStringGrid返信 削除
2012/3/14 (水) 06:55:47 yoshida
はずしていそうですが、ちょっと補足です。

>FMX.Gridソースを修正する必要がありました。

この方法は、win32でもLiveBindingを使うと、コンパイルがダメのようで、やめておいた方がいいです。

たとえば、\Samples\FireMonkey\DataCube\DataRoom.dproj

>[DCC 致命的エラー] Unit7.pas(20): F2051 ユニット Fmx.Bind.Editors は
>異なるバージョンの FMX.Grid.TCustomGrid.SetRowCount によりコンパイルされています。


TGrid周りはUpdate4で、Macで描画/編集操作がいまいち(というか悪化?)で試しましたが、
VCLのような自由度もなく、あくまでLiveBinding向けのGridのようです。
他にも、IDEが遅くなった感とか、固まる頻度が多くなったとか発展途上のようで
今のところ、あまり深入りする価値はなさそうです。
3'dパーティ製Gridを期待しつつ、次のUpdate待ちになりそうです(あるのか?)
FM自体は素晴らしいけど、IDEビジネスへの無理やり感が心配というか。


[5897] Re7:FMXなStringGrid返信 削除
2012/3/14 (水) 06:53:28 yoshida
> procedure TForm1.FColEnter(Sender: TObject);

TControl.FChildrenあたりにCellを持ち、Paint時のRectを保持しているかも〜という感じで
ソースをよく見るとOnEnterのSenderは、Columnですし勘違いしていました。失礼。


[5884] Re5:FMXなStringGrid返信 削除
2012/3/13 (火) 08:24:35 Syake
▼ Mr.XRAYさん

> ん? 横スクロールバーが...

微妙ですね。
たまたま私の所は、行高のキリが良くて気がつきませんでした。

どうも
ShowHeader := False;
が悪さをしているようです。
ShowHeader := True;
なら問題ないと思います。

って、そういう問題ではないですね。

[5893] Re6:FMXなStringGrid返信 削除
2012/3/13 (火) 20:50:38 Mr.XRAY
▼ Syakeさん

> って、そういう問題ではないですね。

スクロールすると,OnPaintが発生しますから,その辺りのコードじゃないかと
思うんですが,未確認です.


INCM/CMT
Cyclamen v3.82