TListview中的潜在问题-无法识别TDateTimeField的DisplayFormat



我做了一个简单的例子。显示格式适用于CustomerAmount(整数(,但不适用于CustomerDate(Tdatetime(。TListview似乎不尊重TDateTime的displayFormat。

示例表有3个字段。

行显示消息(FDMemTable1.FieldByName('CustomerDate'(.displaytext(-->即使没有GetText事件,DisplayText也能工作

它正确显示日期格式"dd-mmm(ddd("。

但当它转到TListview时,它不使用DisplayText。但是TIntegerField在TListview中使用了正确的DisplayText,所以TListview处理的方式不同。

type
TForm1 = class(TForm)
ListView1: TListView;
Button1: TButton;
FDMemTable1: TFDMemTable;
BindSourceDB1: TBindSourceDB;
FDMemTable1CustomerID: TIntegerField;
FDMemTable1CustomerName: TStringField;
BindSourceDB2: TBindSourceDB;
BindingsList1: TBindingsList;
FDMemTable1CustomerDate: TDateTimeField;
FDMemTable1CustomerAmount: TIntegerField;
procedure Button1Click(Sender: TObject);
private
FLinkFillControlToField : TLinkFillControlToField;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure TForm1.Button1Click(Sender: TObject);
begin
with FDMemTable1 do
begin
Open;
Append;
FieldByName('CustomerID').AsInteger := 1;
FieldByName('CustomerAmount').AsInteger := 1250000;
FieldByName('CustomerName').AsString := 'ABC';
FieldByName('CustomerDate').AsDateTime := NOW();
Post;
Append;
FieldByName('CustomerID').AsInteger := 2;
FieldByName('CustomerAmount').AsInteger := 2550000;
FieldByName('CustomerName').AsString := 'XYZ';
FieldByName('CustomerDate').AsDateTime := NOW()+1;
Post;
Append;
FieldByName('CustomerID').AsInteger := 3;
FieldByName('CustomerAmount').AsInteger := 3250000;
FieldByName('CustomerName').AsString := 'XYZ';
FieldByName('CustomerDate').AsDateTime := NOW()+2;
Post;
(FDMemTable1.FieldByName('CustomerAmount') as TIntegerField).DisplayFormat
:= '#,###,###';
(FDMemTable1.FieldByName('CustomerDate') as TDateTimeField).DisplayFormat
:= 'dd yyyy (ddd)';
end;
showmessage( FDMemTable1.FieldByName('CustomerDate').displaytext );
// this .DisplayText works but not below
if not Assigned(FLinkFillControlToField) then
begin
FLinkFillControlToField := TLinkFillControlToField.Create(BindingsList1);
FLinkFillControlToField.Control := listview1;
with FLinkFillControlToField do
begin
Category := 'Quick Bindings';
Track := False;
Direction := linkDataToControl;
AutoActivate := False;
AutoFill := True;
BindSourceDB1.DataSource.Enabled := True;
FillDataSource := BindSourceDB1;
end;
end;
with FLinkFillControlToField do
begin
FillHeaderFieldName := 'CustomerName';
with FillExpressions.AddExpression do
begin
//SourceMemberName := 'CustomerID';
SourceMemberName := 'CustomerAmount';
ControlMemberName := 'Text1';
end;
with FillExpressions.AddExpression do
begin
SourceMemberName := 'CustomerDate';
ControlMemberName := 'Text2';
end;
end;
FLinkFillControlToField.Active := True;
end;
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 404
ClientWidth = 763
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object ListView1: TListView
ItemAppearanceClassName = 'TDynamicAppearance'
ItemEditAppearanceClassName = 'TDynamicAppearance'
HeaderAppearanceClassName = 'TListHeaderObjects'
FooterAppearanceClassName = 'TListHeaderObjects'
Position.X = 16.000000000000000000
Position.Y = 24.000000000000000000
Size.Width = 561.000000000000000000
Size.Height = 353.000000000000000000
Size.PlatformDefault = False
ItemAppearanceObjects.ItemObjects.ObjectsCollection = <
item
AppearanceObjectName = 'Text1'
AppearanceClassName = 'TTextObjectAppearance'
Appearance.Width = 223.000000000000000000
Appearance.Height = 44.000000000000000000
end
item
AppearanceObjectName = 'Text2'
AppearanceClassName = 'TTextObjectAppearance'
Appearance.Width = 208.000000000000000000
Appearance.Height = 44.000000000000000000
Appearance.PlaceOffset.X = 326.000000000000000000
end>
ItemAppearanceObjects.ItemEditObjects.ObjectsCollection = <
item
AppearanceObjectName = 'Text1'
AppearanceClassName = 'TTextObjectAppearance'
end>
end
object Button1: TButton
Position.X = 592.000000000000000000
Position.Y = 24.000000000000000000
Size.Width = 161.000000000000000000
Size.Height = 57.000000000000000000
Size.PlatformDefault = False
Text = 'Button1'
OnClick = Button1Click
end
object FDMemTable1: TFDMemTable
FetchOptions.AssignedValues = [evMode]
FetchOptions.Mode = fmAll
ResourceOptions.AssignedValues = [rvSilentMode]
ResourceOptions.SilentMode = True
UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
UpdateOptions.CheckRequired = False
UpdateOptions.AutoCommitUpdates = True
Left = 576
Top = 128
object FDMemTable1CustomerID: TIntegerField
FieldName = 'CustomerID'
end
object FDMemTable1CustomerName: TStringField
FieldName = 'CustomerName'
Size = 30
end
object FDMemTable1CustomerDate: TDateTimeField
FieldName = 'CustomerDate'
end
object FDMemTable1CustomerAmount: TIntegerField
FieldName = 'CustomerAmount'
end
end
object BindSourceDB1: TBindSourceDB
DataSet = FDMemTable1
ScopeMappings = <>
Left = 576
Top = 192
end
object BindSourceDB2: TBindSourceDB
DataSet = FDMemTable1
ScopeMappings = <>
Left = 576
Top = 248
end
object BindingsList1: TBindingsList
Methods = <>
OutputConverters = <>
Left = 20
Top = 5
end
end

为了理解为什么CustomerDate字段似乎不尊重您设置的格式,您需要首先阅读TDateTimeField.DisplayFormat 上的文档

在那里你会发现下一张纸条:

DisplayFormat不影响AsString属性的值。

在那之后,你可能会想:"但我不是使用AsString来检索值,而是使用DisplayText。所以这应该仍然有效">

好吧,如果你去阅读TField.DisplayText上的文档,你可以找到下一个解释

如果字段具有OnGetText事件处理程序,则DisplayText是当其Display Textext参数中返回的值。否则,DisplayTextAsString属性的值。

正如您所看到的,除非分配了OnGetText偶数处理程序,否则DisplayText将返回AsString属性的值。由于TDateTimeField的显示格式不会影响AsString属性的结果,因此日期不会以所需的显示格式表示。

为了解决您的问题,您应该将OnGetText事件处理程序分配给TDateTimeField,并适当地格式化通过所述事件的Text参数返回的文本。


您是否尝试使用CustomFormat
CustomFormat:='FormatDateTime("dd-yyyy(ddd(",%s(';
with FillExpressions.AddExpression do
begin
SourceMemberName := 'CustomerDate';
ControlMemberName := 'Text2'; 
CustomFormat := 'FormatDateTime("dd yyyy (ddd)",%s)';          
end;

问候
Moskw@

最新更新