Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Overriding Drag & drop behaviour of Fields

151 views
Skip to first unread message

Dirk Naudts

unread,
Apr 5, 2002, 4:26:04 AM4/5/02
to
Hi,

When I add all fields is Fields-editor, I can drag them to a form and the
result of the operation is a set of TDbedit/TdbCheckbox and TLabels on that
form,
and if necessary an additional datasource component as well.

I'd like to override this behaviour, so that I can have control over which
Data aware components should be placed on the form (some fields require
TDblookupcombo's, or even 3rd party comps)

How can I accomplish this ?

Thanks,
Dirk Naudts.


serge gubenko

unread,
Apr 5, 2002, 4:58:28 AM4/5/02
to
"Dirk Naudts" <dirk....@aucxistrading.com> wrote in message
news:3cad6d0d$1_2@dnews...

Hi, Dirk

The most easy way is to write and register new component editor for the
desired dataset (or for all datasets). There you could override a
GetDSDesignerClass method and return class of your own dataset editor. You
need this class, as it could define the class of the control, which would be
then created when you'll drag and drop the field into the form. The
designer's method to override is GetControlClass, there you need to return a
string name of the component you want to be created. Below is a simple
example (it would create a TComboBox for every field you're dragging):
_____________________________________
uses .... DesignIntf, ... DBReg, DSDesign...

TMyTestDataSetEditor = class(TDataSetEditor)
public
function GetDSDesignerClass: TDSDesignerClass; override;
end;

{..}

type
TMyDSDesigner = class(TDSDesigner)
public
function GetControlClass(Field: TField): string; override;
end;

function TMyDSDesigner.GetControlClass(Field: TField): string;
begin
Result:='TComboBox'; {<-- set here class of the control, you wish to
create}
end;

function TMyTestDataSetEditor.GetDSDesignerClass: TDSDesignerClass;
begin
Result:=TMyDSDesigner;
end;

Here's how you need to register it:
procedure Register;
begin
...
RegisterComponentEditor(TMyTestDataSet, TMyTestDataSetEditor);
...
_____________________________________
In order to get your package compiled, you need to add the dcldb.dcp (from
the $Delphi\Lib dir) to its requires clause.

Best regards, Serge Gubenko


Dirk Naudts

unread,
Apr 5, 2002, 5:15:33 AM4/5/02
to
Hi Serge

Thanks for the quick response. But after trying it, I think you made the
sample in D6, I'm using D5 ;-(

Is this possible in D5 as well ?

Thanks

Dirk Naudts.

PS. I assume I can extend the GetcontrolClass to resturn different controls
depending on fieldname/fieldclass, or whatever I want, right ?

Dirk Naudts

unread,
Apr 5, 2002, 5:23:26 AM4/5/02
to
Sorry Serge, I simply changed DesignInt into DsgnInt and is compiles ok now.

I'll test it now ;-)


"Dirk Naudts" <dirk....@aucxistrading.com> wrote in message

news:3cad78a6$1_1@dnews...

Dirk Naudts

unread,
Apr 5, 2002, 6:31:42 AM4/5/02
to
Ok Serge, this works great !!

Can I go a little further now ?

When doing the drag&drop Delphi (along with the controlclass I tell it to)
also puts a Tlabel above the control.
I'd like to have control over this Tlabel component as well, change it into
my own controlclass, and choose where to position it.

Is this possible ?

Thanks,

Dirk Naudts.

"serge gubenko" <serge_...@yahoo.com> wrote in message
news:3cad755c_2@dnews...

serge gubenko

unread,
Apr 5, 2002, 3:38:36 PM4/5/02
to
<snip>

> Can I go a little further now ?
>
> When doing the drag&drop Delphi (along with the controlclass I tell it to)
> also puts a Tlabel above the control.
> I'd like to have control over this Tlabel component as well, change it
into
> my own controlclass, and choose where to position it.
>
> Is this possible ?
>

<snip>

It's possible, but I'm afraid not that simple, as it was with just a
different control class. I suppose, in order to do it right, you should
write your own fields editor and provide it with your own realizations of
TFieldsTarget and TDragFields classes. And in the TFieldsTarget.DragDrop
method you could create control with the label of your own class
(DSDesign.pas would be a good example). The main problem is in the
CreateFieldControl function, it exists in the DrpCtrls unit (unfortunately,
no sources for it) and takes care about all "components creation" process.
And, I guess, there is no way to hook into this routine and change TLabel to
TStaticText, for example. Actually, you could call this function with false
in the last parameter and label will not be created at all. Instead you'll
need manually create and place in the right position control, which is
supposed to replace the label. Below is a simple example, I was debugging it
on D5, and it seemed to work fine. I've managed without new fields editor,
instead I've registered new drag target for existing one. So I wouldn't
guaranty that it's a proper solution. Yes, and it should create a
TStaticText instead of usual TLabel :)
____________________________________________
uses ... LibIntf, DSDesign, DsnDBCst, DrpCtrls...

type
TMyFieldsTarget = class(TDragTarget)
public
procedure DragDrop(Target: TObject; Source: TObject; X: Integer;
Y: Integer); override;
function DragOver(Target: TObject; Source: TObject; X: Integer;
Y: Integer; State: TDragState): Boolean; override;
end;

TDragFields = class(TDragControlObject)
private
FEditor: TFieldsEditor;
end;

procedure TMyFieldsTarget.DragDrop(Target: TObject; Source: TObject;
X: Integer; Y: Integer);
var
XSourceRoot: TComponent;
XEditor: TFieldsEditor;
XFieldList: TList;
XField: TField;
XControl: TControl;
XStaticText: TStaticText;
i: integer;
begin
XSourceRoot:=TDragFields(Source).FEditor.Designer.GetRoot;
if not Designer.IsComponentLinkable(XSourceRoot) then
if MessageDlg(Format(SDSLinkForms, [Designer.GetRoot.Name,
XSourceRoot.Name]), mtConfirmation, mbYesNoCancel, 0) <> idYes
then exit
else
Designer.MakeComponentLinkable(XSourceRoot);
XFieldList:=TList.Create;
try
XEditor := TDragFields(Source).FEditor;
with XEditor do
for I := 0 to FieldListBox.Items.Count - 1 do
if FieldListBox.Selected[I] then
XFieldList.Add(FieldListBox.Items.Objects[I]);
Screen.Cursor := crHourGlass;
try
for i:=0 to XFieldList.Count - 1 do begin
XField:=TField(XFieldList[I]);
XControl:=CreateFieldControl(
Designer, XField, XEditor.DSDesigner.GetControlClass(XField),
TComponent(Target), X, Y, false);
XStaticText:=TStaticText(Designer.CreateComponent(
TStaticText, TWinControl(Designer.GetRoot),
X, Y + XControl.Height + 1, 17, 30));
XStaticText.Caption:=XField.FieldName;
Y:=XControl.Top + XControl.Height + XStaticText.Height + 6;
end;
finally
Screen.Cursor := crDefault;
end;
finally
XFieldList.Free;
end;
end;

function TMyFieldsTarget.DragOver(Target: TObject; Source: TObject; X:
Integer;
Y: Integer; State: TDragState): Boolean;
begin
Result:=True;
end;

{...}

initialization
if Assigned(CompLib)
then CompLib.RegisterDragTarget('TDragFields', TMyFieldsTarget);
____________________________________________
Best regards, Serge Gubenko


0 new messages