Delphi 放置一个devexpress dbgridview单元格';使用不同的文本格式编辑内容
使用Devexpress cxGrid,我有一个tablegridview,其中显示了一个包含三个varchar字段的db表(30);ID、名称和描述 实际cxgrid外观:Delphi 放置一个devexpress dbgridview单元格';使用不同的文本格式编辑内容,delphi,devexpress,Delphi,Devexpress,使用Devexpress cxGrid,我有一个tablegridview,其中显示了一个包含三个varchar字段的db表(30);ID、名称和描述 实际cxgrid外观: ID名称描述 1名称1说明1 2名称2说明2 . ... ... X名称X说明3 我希望这两个字段用#13(两行)连接和分隔,每行使用特殊的文本格式(例如,第一行用粗体,第二行用斜体) 我想要的cxgrid外观: ID名称和描述(只有一个字段而不是两个) 1名称1 说明1 2名称2 说明2
ID名称描述
1名称1说明1
2名称2说明2
. ... ...
X名称X说明3
我希望这两个字段用#13(两行)连接和分隔,每行使用特殊的文本格式(例如,第一行用粗体,第二行用斜体)
我想要的cxgrid外观:
ID名称和描述(只有一个字段而不是两个)
1名称1
说明1
2名称2
说明2
. 名称…
描述
3命名3
描述
任何帮助都将不胜感激 我尝试了评论中建议的两种可能性,即在中使用自定义绘图 标准的DBTableView和使用DBBandeTableView,两者似乎都不提供 开箱即用的理想解决方案 对于像我这样的非专家来说,使用DBTableView很快就会遇到麻烦:
- 尽管在
文本下方绘制名称
文本很简单, 它充满了困难,比如如何确定描述
单元格的边界 绘制Name
如何避免网格绘制残余轮廓 如果绘制了说明时
,则说明
单元格和标题会是什么 通常说明
- 将ClientDataSet,
添加到表单中,为ID、名称和描述字段添加持久字段CDS1
- 将DBBandeTableView添加到cxGrid,并使用TDataSource将其连接到
CDS1
- 在其中创建两个波段,并为它们提供标题
和Band
,以便于参考Band2
- 为
、ID
和Name
列创建列。设置其Description
属性 编辑文本属性
- 在DBBandeTableView编辑器中,将
列添加到ID
中,并将Band
名称添加到
列到Description
使用到Band2
列的子属性BandIndex
属性。同时设置位置
列的Description
子属性 到1,使其位于RowIndex
字段下方名称
type
TForm1 = class(TForm)
CDS1: TClientDataSet;
CDS1ID: TAutoIncField;
DS1: TDataSource;
DBNavigator1: TDBNavigator;
CDS1Name: TStringField;
CDS1Description: TStringField;
cxGrid1Level1: TcxGridLevel;
cxGrid1: TcxGrid;
cxGrid1DBBandedTableView1: TcxGridDBBandedTableView;
cxGrid1DBBandedTableView1ID: TcxGridDBBandedColumn;
cxGrid1DBBandedTableView1Name: TcxGridDBBandedColumn;
cxGrid1DBBandedTableView1Description: TcxGridDBBandedColumn;
procedure FormCreate(Sender: TObject);
private
procedure CustomDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
protected
public
end;
var
Form1: TForm1;
[...]
procedure TForm1.CustomDrawCell(Sender:
TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo:
TcxGridTableDataCellViewInfo; var ADone: Boolean);
var
ACol : TcxGridDBBandedColumn;
begin
ACol := TcxGridDBBandedColumn(AViewInfo.Item);
if ACol = cxGrid1DBBandedTableView1Name then
ACanvas.Font.Style := ACanvas.Font.Style + [fsBold]
else
if ACol = cxGrid1DBBandedTableView1Description then
ACanvas.Font.Style := ACanvas.Font.Style + [fsItalic];
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
begin
CDS1.CreateDataSet;
CDS1.InsertRecord([1, 'Name1', 'Description1']);
CDS1.InsertRecord([2, 'Name12', 'Description2']);
CDS1.First;
cxGrid1DBBandedTableView1ID.PropertiesClassName := 'TcxTextEditProperties';
cxGrid1DBBandedTableView1ID.OnCustomDrawCell := CustomDrawCell;
cxGrid1DBBandedTableView1Name.PropertiesClassName := 'TcxTextEditProperties';
cxGrid1DBBandedTableView1Name.OnCustomDrawCell := CustomDrawCell;
cxGrid1DBBandedTableView1Description.PropertiesClassName := 'TcxTextEditProperties';
cxGrid1DBBandedTableView1Description.OnCustomDrawCell := CustomDrawCell;
end;
end.
对于如此简单的任务,CustomDrawCell看起来是一个非常繁重的解决方案 理想的解决方案是使用具有HTML列的TCxGrid,因此您只需在其上显示一个计算字段,例如(将[]替换为): [html][b]名称1[/b][br][i]说明1[/i][html] 问题是TCxGrid没有HTML列,但正如其他人所说,您可以使用RichEdit列。因此,您也可以使用RTF而不是HTML构建此解决方案 使用Word(或Windows文件夹上的Write)创建示例并查找文本的RTF表示形式:
{\rtf1\ansi\ansicpg1252\deff0\deflang3082{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
\viewkind4\uc1\pard\sa200\sl276\slmult1\lang10\b\f0\fs22 Name 1\par
\b0\i Description 1\i0\par
}
现在,向数据集中添加一个计算字段,返回要显示的格式化文本的RTF表示形式:
procedure TMyForm.MyQueryCalcFields(DataSet: TDataSet);
var FormattedText: string;
begin
FormattedText := '{\rtf1\ansi\ansicpg1252\deff0\deflang3082{\fonttbl{\f0\fnil\fcharset0 Calibri;}}' + sLineBreak +
'\viewkind4\uc1\pard\sa200\sl276\slmult1\lang10\b\f0\fs22 ' +
Dataset.FieldByName('Name').AsString + '\par' + sLineBreak +
'\b0\i ' + Dataset.FieldByName('Description').AsString + '\i0\par' + sLineBreak +
'}';
Dataset.FieldByName('FormattedText').Value := FormattedText;
end;
最后,您只需将列的属性设置为RichEdit,并将此格式化文本绑定到该列即可获得所需的结果。最后,尽管有一些困难,但在某些人的帮助下,这是使用OnCustomDraw而不是使用BandeTableView的完美解决方案,RichEditColumn或预览方法
procedure TForm1.cxGrid1DBTableView1NameCustomDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
Function VarToText(AVal: Variant): String;
Begin
If VarIsNull(AVal)
Then Result := ''
Else Result := VarToStr(AVal);
End;
Var
AValue1, AValue2: Variant;
AText: String;
ARect: TRect;
Begin
ARect := AViewInfo.ClientBounds;
AValue1 := Sender.DataController.Values[AViewInfo.GridRecord.Index,
cxGrid1DBTableView1NAME.Index];
AValue2 := Sender.DataController.Values[AViewInfo.GridRecord.Index,
cxGrid1DBTableView1DESCRIPTION.Index];
ACanvas.Font.Style := [fsBold];
If VarIsNull(AValue1)
Then Begin
AText := VarToText(AValue2);
ACanvas.Font.Style := [fsItalic];
ACanvas.DrawTexT(AText, ARect, taLeftJustify, vaCenter, True,
False);
End
Else If VarIsNull(AValue2)
Then Begin
AText := VarToText(AValue1);
ACanvas.Font.Style := [fsBold];
ACanvas.DrawTexT(AText, ARect, taLeftJustify, vaCenter, True,
False);
End
Else Begin
ACanvas.DrawTexT(VarToText(AValue1), ARect, taLeftJustify,
vaTop, True, false);
ARect.Top := ARect.Top +
ACanvas.TextHeight(VarToText(AValue1));
ACanvas.Font.Style := [fsItalic];
ACanvas.DrawTexT(VarToText(AValue2), ARect, taLeftJustify,
vaBottom, True, False);
End;
ADone := True;
end;
我来这里是想澄清一下。在获取数据时,您可能需要在SQL中进行连接。在文档中查找多行,如果我没记错的话,它涉及到对列属性使用备注,并设置视图的OptionView.RowAutoHeight。对于粗体和斜体字体样式,您可以使用列OnGetContentStyle事件。感谢您的回复,但主要问题是如何使两行具有不同的文本格式(粗体和斜体),因为将值串联并将其放入多行在位编辑器并不难。感谢您的澄清,我想你已经把你想要的部分归档了。您是否尝试过使用RichEditProperties作为列的属性?我不认为使用CustomDraw事件是可行的,以不同样式绘制多行文字的部分可能是可归档的,但要与基础设计保持一致,您需要能够正确计算ViewInfo。RichEdit是我首先想到的能够拥有你想要的风格的功能。你是否排除使用带状表格视图?这将允许您将列排列到多行。感谢这种逐步的方法,但结果并不像预期的那么好,顺便说一句,有一种与您类似的解决方案,但使用0行编码,这是预览的实现,因此,通过这两个属性.Preview.Visible=True和.Preview.Column=dbgvDESCRIPTION,并使用两种cxstylerepository样式,粗体表示名称列,斜体表示描述,这将使结果更接近您的结果!因此,我认为DBBandeTableView永远不会