『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;
DBGridのカスタム描画にはDrawCellではなくて
DrawColumnCellを使うのではないですか?
torさん、有難うございます。
DrawColumnCellで解決する事を最初に考えたのですが、
データカラムの高さをデータの改行状況を見て動的に変更する
必要がありました。
DBGridには個別行の高さを設定するRowHeightsメソッドと
行を表すRowプロパティが公開されていない(protected)ため、
TDBGridを継承するクラスで試す事にしました。
DrawColumnCellで解決する方法をご存知でしたらご教授ください。
データセットを開くときに、「しばらくお待ち下さい」とか出して、レコード総なめして高さ出しておくのはだめなの?
スクロールして新たに描画されるごとに、全体の高さが変化していくのは変な感じがするけど。
なお、DrawColumnCell を使うなら、Column.Field で、DB値を確認できるような気がします。
いずれにしても描画処理の中で行の高さを変えるのは問題ありですね。
フィールドが複数あった場合、高さが変わる→他のセルが再描画される→また高さが変わると無限ループに陥る危険があります。
さて、DrawColumnCellの中であれば、その行に対応するレコードが選択された状態になっているので、Column引数を通じて正しい値が取り出せます。
その時の行番号はDataLink.ActiveRecordで分かります。
逆にDrawColumnCell以外のところで行にアクセスしたかったら、DataLink.ActiveRecordを一時的に変更すればいいということです。
torさん、ぽむぽむさん、ご意見有難うございます。
色々試しましたが、スッキリ解決とはいきませんでした。
代替策としてTDBCtrlGridにTDBMemoを置き、縦スクロール複数改行データを
表示するようにしました。
解決とします。
ツイート | ![]() |