自己编写的数据库控件,如何自动更新内容(100分)

  • 主题发起人 yinxianglong
  • 开始时间
Y

yinxianglong

Unregistered / Unconfirmed
GUEST, unregistred user!
问题1
当DataSource发生变化时自己编写的数据库控件如何知道,
如TDBGrid控件,当数据库打开时自动更新表格中的内容
问题2
我自己编写的控件中的 Property ShowCursor:Boolean,为什么只能在程序运行过程中起作用,在编程过程中设置的值为什么起不作用

unit MyChart;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, TeeProcs, TeEngine, Chart, Math,Series;

type

TYinChart = class(TChart)

private
{ Private declarations }
Cursor:TShape;
FShowCursor:Boolean;
protected

{ Protected declarations }
procedure SetShowCursor(b:Boolean);
procedure MouseMove(Shift: TShiftState; X, Y: Integer);override;
public
{ virturl or override or constructor}
constructor Create(AOwner:TComponent); override ;

{ property Function And Procedure }


{ normal }
function GetXCursorPos:double;

function GetMaxX:double;

function GetMinX:double;

function GetMaxYInViewport:double;

function GetMinYinViewport:double;

procedure SetRangeX(X1,X2:Double);

procedure SetRangeY(X1,X2:Double);overload;

procedure SetRangeY;overload;

procedure ScrollX(step:Double);


procedure InvertXAxis(Value:Boolean);

procedure SetDefault;

function FindX(Series:TChartSeries;value:Double;operation:integer):Integer;//0 : <= ; 1:>=;


{ Public declarations }
published
property ShowCursor:Boolean read FShowCursor write SetShowCursor Default False;

{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('YinXL', [TYinChart]);
end;

{ virturl or override or constructor}

constructor TYinChart.Create(AOwner:TComponent);
begin
inherited Create(AOwner);

//self.init
Cursor:=TShape.Create(Self);
Cursor.Visible:=false;
self.InsertControl(Cursor);
Cursor.Parent:=Self;
Cursor.Width:=2;
Cursor.Pen.Mode:=pmNotXor;
FShowCursor:=False;
end;

procedure TYinChart.SetRangeY;
begin
SetRangeY(GetMaxYInViewport,GetMinYInViewport);
end;


procedure TYinChart.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
if (Shift=[ssLeft]) and (ShowCursor=True) then
Cursor.left:=X;

if (Shift=[ssLeft]) and (ShowCursor=True)and (x<BottomAxis.IStartPos) then
Cursor.left:=BottomAxis.IStartPos;

if (Shift=[ssLeft]) and (ShowCursor=True)and (x>BottomAxis.IEndPos) then
Cursor.left:=BottomAxis.IEndPos;

inherited MouseMove(Shift,x,y);
end;

{ property Function And Procedure }

procedure TYinChart.SetShowCursor(b:Boolean);
begin
FShowCursor:=b;
AllowZoom:=False;
Cursor.Visible:=b;
Cursor.Top :=LeftAxis.IStartPos;
Cursor.Height:=LeftAxis.IEndPos-LeftAxis.IStartPos;

if Cursor.Left<BottomAxis.IStartPos then
Cursor.Left:=BottomAxis.IStartPos;
if Cursor.Left>BottomAxis.IEndPos then
Cursor.Left:=BottomAxis.IEndPos;
end;


{ normal }
function TYinChart.GetXCursorPos:double;
begin
with BottomAxis do
begin
Result:=(Cursor.Left-IStartPos+1) / (IEndPos-IStartPos) * (Maximum-Minimum) + Minimum;
end;
end;

function TYinChart.FindX(Series:TChartSeries;value:Double;operation:integer):Integer;//0 : value<= ; 1:value>=;
var
i:integer;
begin
case operation of
1:
begin
for i:=series.count-1 downto 0 do
if series.XValue<=value+0.5 then
begin
result:=i;
exit;
end;
result:=0;
end;
0:
begin
for i:=0 to series.count-1 do
if series.XValue>=value-0.5 then
begin
result:=i;
exit;
end;

result:=series.count-1;
end;
else
result:=-1;
end;



end;

function TYinChart.GetMaxX:double;
var
i:integer;
begin
if self.seriesList.Count = 0 then
begin
result:=0;
exit;
end;

result:=self.Series[0].MaxXValue;

for i:=1 to SeriesList.Count-1 do
begin
if result<Series.MaxXValue then
result:=Series.MaxXValue;
end;
end;



function TYinChart.GetMinX:double;
var
i:integer;
begin
if SeriesList.count = 0 then
begin
result:=0;
exit;
end;

result:=self.Series[0].MinXValue;

for i:=1 to self.SeriesList.Count-1 do
begin
if result>Series.MinXValue then
result:=Series.MinXValue;
end;
end;

function TYinChart.GetMaxYInViewport:double;
var
i,j,k:integer;
MaxS:integer;
MinS:integer;
TMaxY:Double;
b:TBarSeries;
begin


result:=-99999999.00;

for i:=0 to Self.seriesList.Count-1 do
begin
minS:=Self.FindX(series,BottomAxis.Minimum,1);
maxS:=Self.FindX(series,BottomAxis.maximum,0);
for j:=mins to maxs do
begin
if result<Series.YValue[j] then
result:=Series.YValue[j];
end;
end;


for i:=0 to seriesList.Count-1 do
begin

B:=TBarSeries(Series);

if (Series is TBarSeries) and (B.MultiBar=mbStacked) then
begin

minS:=Self.FindX(series,BottomAxis.Minimum,1);
maxS:=Self.FindX(series,BottomAxis.maximum,0);

for j:=Mins to Maxs do
begin
TMaxy:=0;

for k:=0 to seriesList.Count-1 do if (Series is TBarSeries) and (B.MultiBar=mbStacked) then
TMaxY:=Series[k].YValue[j]+TMaxY;

if TMaxY>=Result then result:=TMaxY
end; //end for

Exit;

end;//endif
end;//end for
end;//end function



function TYinChart.GetMinYInViewport:double;
var
i,j:integer;
MaxS:integer;
MinS:integer;
TMinY:Double;
b:TBarSeries;
begin


result:=99999999.00;

for i:=0 to Self.seriesList.Count-1 do
begin
minS:=Self.FindX(series,BottomAxis.Minimum,1);
maxS:=Self.FindX(series,BottomAxis.maximum,0);
B:=TBarSeries(Series);
for j:=mins to maxs do
begin
if (result>Series.YValue[j]) and not (Series is TBarSeries) and (B.MultiBar<>mbStacked) then
result:=Series.YValue[j];
end;
end;

for i:=0 to seriesList.Count-1 do
begin

B:=TBarSeries(Series);

if (Series is TBarSeries) and (B.MultiBar=mbStacked) then
begin

minS:=Self.FindX(series,BottomAxis.Minimum,1);
maxS:=Self.FindX(series,BottomAxis.maximum,0);

for j:=Mins to Maxs do
begin
TMinY:=Series.YValue[j];
if TMinY<=Result then result:=TMinY;
end; //end for

Exit;

end;//endif
end;//end for
end;//end function


procedure TYinChart.SetRangeX(X1,X2:Double);
begin
BottomAxis.Maximum:=Max(X1,X2);
BottomAxis.Minimum:=Min(X1,X2);
end;


procedure TYinChart.SetRangeY(X1,X2:Double);
begin
LeftAxis.Maximum:=Max(X1,X2);
LeftAxis.Minimum:=Min(X1,X2);
end;


procedure TYinChart.ScrollX(step:Double);
begin
if step>0 then
begin
BottomAxis.Maximum:=step+BottomAxis.Maximum;
BottomAxis.Minimum:=step+BottomAxis.Minimum;
end
else
begin
BottomAxis.Minimum:=step+BottomAxis.Minimum;
BottomAxis.Maximum:=step+BottomAxis.Maximum;
end

end;


procedure TYinChart.InvertXAxis(Value:Boolean);
begin
BottomAxis.Inverted:=Value;
end;

procedure TYinChart.SetDefault;
begin
LeftAxis.Automatic:=false;
BottomAxis.Automatic:=false;
View3d:=False;
end;


end.
 
第一个问题:

//DBDateTimePicker是从TDateTimePicker继承,可以象DBEdit一样使用.
{
作者:沈前卫 shenqw@cmmail.com 2000-02-28 0:45
转贴请保持本文的完整性
}
unit DBDateTimePicker;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls,DB,dbctrls;

type
TDBDateTimePicker = class(TDateTimePicker)
private
{ Private declarations }
FFieldDataLink:TFieldDataLink;
function GetReadOnly:boolean;
procedure SetReadOnly(Value:boolean);
function GetDataField:string;
procedure SetDataField(Value:string);
function GetDataSource:TDataSource;
procedure SetDataSource(Value:TDataSource);
function GetField:TField;
procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
procedure CMExit(var Message:TCMExit);message CM_EXIT;
protected
{ Protected declarations }
procedure FDataChange(Sender:TObject);
procedure FUpdateData(Sender:TObject);
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
public
{ Public declarations }
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
property Field:TField read GetField;
published
{ Published declarations }
property Anchors;
property BiDiMode;
property CalAlignment;
property CalColors;
property Constraints;
property DataSource:TDataSource read GetDataSource write SetDataSource;
property DataField:string read GetDataField write SetDataField;
property ReadOnly:boolean read GetReadOnly write SetReadOnly;
// The Date, Time, ShowCheckbox, and Checked properties must be in this order:
property ShowCheckbox;
property Checked;
property Color;
property DateFormat;
property DateMode;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
property ImeMode;
property ImeName;
property Kind;
property MaxDate;
property MinDate;
property ParseInput;
property ParentBiDiMode;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnClick;
property OnCloseUp;
property OnChange;
property OnDropDown;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnStartDock;
property OnStartDrag;
property OnUserInput;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Data Controls', [TDBDateTimePicker]);
end;

{ TDBDateTimePicker }

procedure TDBDateTimePicker.CMExit(var Message: TCMExit);
begin
try
FFieldDataLink.UpdateRecord;
except
Self.SetFocus;
raise;
end;
inherited;
end;

procedure TDBDateTimePicker.CNNotify(var Message: TWMNotify);
begin
FFieldDataLink.Edit;
inherited;
FFieldDataLink.Modified;
end;

constructor TDBDateTimePicker.Create(AOwner: TComponent);
begin
inherited Create(AOwner);

FFieldDataLink:=TFieldDataLink.Create;
FFieldDataLink.ReadOnly:=False;
FFieldDataLink.Control:=Self;
FFieldDataLink.OnDataChange:=FDataChange;
FFieldDataLink.OnUpdateData:=FUpdateData;
end;

destructor TDBDateTimePicker.Destroy;
begin
FFieldDataLink.Free;
FFieldDataLink:=nil;

inherited;
end;

procedure TDBDateTimePicker.FDataChange(Sender: TObject);
begin
if (FFieldDataLink<>nil) and (FFieldDataLink.Field<>nil) then
begin
Self.Date:=Trunc(FFieldDataLink.Field.AsDateTime);
Self.Time:=Frac(FFieldDataLink.Field.AsDateTime);
end;
end;

procedure TDBDateTimePicker.FUpdateData(Sender: TObject);
begin
if (FFieldDataLink<>nil) and (FFieldDataLink.Field<>nil) then
FFieldDataLink.Field.AsDateTime:=TDateTime(Date);
end;

function TDBDateTimePicker.GetDataField: string;
begin
Result:=FFieldDataLink.FieldName;
end;

function TDBDateTimePicker.GetDataSource: TDataSource;
begin
Result:=FFieldDataLink.DataSource;
end;

function TDBDateTimePicker.GetField: TField;
begin
Result:=FFieldDataLink.Field;
end;

function TDBDateTimePicker.GetReadOnly: boolean;
begin
Result:=FFieldDataLink.ReadOnly;
end;

procedure TDBDateTimePicker.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent,Operation);
if (Operation=opReMove) and (FFieldDataLink<>nil) and
(AComponent=FFieldDataLink.DataSource) then
FFieldDataLink.DataSource:=nil;
end;

procedure TDBDateTimePicker.SetDataField(Value: string);
begin
FFieldDataLink.FieldName:=Value;
end;

procedure TDBDateTimePicker.SetDataSource(Value: TDataSource);
begin
FFieldDataLink.DataSource:=Value;
if Value<>nil then Value.FreeNotification(Self);
end;

procedure TDBDateTimePicker.SetReadOnly(Value: boolean);
begin
FFieldDataLink.ReadOnly:=Value;
end;

end.

 
关于第一个问题:可以参见Delphi自带的源代码中的那些控件编写,
其实就是一个TDataLink类和这个类的几个方法(这个类的方法不太多,而且
从它们的名字也就知道它们是做什么用的了)
 
接受答案了.
 
顶部