DBGridに複数改行した文字列を表示するには?

解決


K-ONE  2010-07-06 19:24:43  No: 38761

『DBGridの見出しを2行に…』の過去ログを参考にあるカラムデータを改行表示しようと試みましたが、DrawCellで現在のARawに対応するDB値が取得できていません。DBの内容は以下の通りです。

日付        項目A
2010/07/01  データ1
2010/07/02  データ2;データ3

項目Aの内容に「;」があれば、改行する仕様です。

想定するグリッド表示

日付        項目A
2010/07/01  データ1
2010/07/02  データ2
            データ3

実行結果(最初の表示)※画面表示直後は全行先頭レコードの値表示

日付        項目A
2010/07/01  データ1
2010/07/02  データ1

実行結果(グリッドの2行目をクリック)※マウスで行移動すると全行選択された行のDB値表示→表示は思い通りになっている

日付        項目A
2010/07/01  データ2
            データ3
2010/07/02  データ2
            データ3

TDBGridを継承して作成したクラスのDrawCellメソッドは以下の通りです。
データの取得方法を変えてみましたが結果は同じでした。
TDBGridを普通に貼り付ければ問題なくリンクされたデータが表示されるので、この関数内でのDB値取得方法が間違っていると思いますが、何方かご存知の方、ご教授ください。

procedure TMultiLineDBGrid.DrawCell(ACol, ARow: Integer; ARect: TRect;
  AState: TGridDrawState);
begin
  inherited;
  vCnt  :=  0;
  if (ARow > 0) and (ACol > 0)  then
    if Columns[ACol-1].Field.FieldName = FFieldName  then
    begin
      InflateRect(ARect, -1, -1);
      Canvas.FillRect(ARect);
      //文字列の;文字を改行コードに変える
      vText :=  Columns[ACol-1].Field.DisplayText;
      //vText :=  GetEditText(ACol, ARow);
      while vText <> EmptyStr do
      begin
        if Pos(';', vText) > 0  then
        begin
          if vCnt = 0 then
            vOutText  :=  Copy(vText, 1, Pos(';', vText) - 1)
          else
            vOutText  :=  vOutText + #13#10 + Copy(vText, 1, Pos(';', vText) - 1);
          Delete(vText, 1, Pos(';', vText));
        end else
        begin
          if vCnt = 0 then
            vOutText  :=  vText
          else
            vOutText  :=  vOutText + #13#10 + vText;
          vText :=  EmptyStr;
        end;
        Inc(vCnt);
      end;
      //カラム表示条件設定
      if vCnt > 1 then
        vFlag :=  DT_VCENTER or AlignFlags[Fields[ACol-1].Alignment]
      else
        vFlag :=  DT_SINGLELINE or AlignFlags[Fields[ACol-1].Alignment];
      //テキスト描画
      DrawText(Canvas.Handle, PChar(vOutText), Length(vOutText), ARect, vFlag);
      //カラムの高さ変更
      RowHeights[ARow]  :=  vCnt * 18;
    end;


tor  2010-07-07 00:49:31  No: 38762

DBGridのカスタム描画にはDrawCellではなくて
DrawColumnCellを使うのではないですか?


K-ONE  2010-07-07 18:45:25  No: 38763

torさん、有難うございます。

DrawColumnCellで解決する事を最初に考えたのですが、
データカラムの高さをデータの改行状況を見て動的に変更する
必要がありました。
DBGridには個別行の高さを設定するRowHeightsメソッドと
行を表すRowプロパティが公開されていない(protected)ため、
TDBGridを継承するクラスで試す事にしました。
DrawColumnCellで解決する方法をご存知でしたらご教授ください。


ぽむぽむ  2010-07-08 18:19:08  No: 38764

データセットを開くときに、「しばらくお待ち下さい」とか出して、レコード総なめして高さ出しておくのはだめなの?
スクロールして新たに描画されるごとに、全体の高さが変化していくのは変な感じがするけど。

なお、DrawColumnCell を使うなら、Column.Field で、DB値を確認できるような気がします。


tor  2010-07-08 20:27:51  No: 38765

いずれにしても描画処理の中で行の高さを変えるのは問題ありですね。
フィールドが複数あった場合、高さが変わる→他のセルが再描画される→また高さが変わると無限ループに陥る危険があります。

さて、DrawColumnCellの中であれば、その行に対応するレコードが選択された状態になっているので、Column引数を通じて正しい値が取り出せます。
その時の行番号はDataLink.ActiveRecordで分かります。
逆にDrawColumnCell以外のところで行にアクセスしたかったら、DataLink.ActiveRecordを一時的に変更すればいいということです。


K-ONE  2010-07-16 05:47:25  No: 38766

torさん、ぽむぽむさん、ご意見有難うございます。
色々試しましたが、スッキリ解決とはいきませんでした。
代替策としてTDBCtrlGridにTDBMemoを置き、縦スクロール複数改行データを
表示するようにしました。
解決とします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加