Delphi_developer
asked on
Docking issue with DevExpress's ExpressDocking library
Hi
I need some help with creating 'docking' appearance with ExpressDocking from DevExpress.com. I use TdxDocSite and TdxDockPanel.
I would like to create simple docking application, with one fixed left dxDocPanel which opens new dxDocPanels on the right. Attached image shows that if I open only one new dxDocPanel, it opens it as 'client' aligned, so they both occupy full dxDocSite.
If I open another 'window', it will align both opened as half/half (2. on image) and if three.. they would all be same width to fully occupy dxDocsite and if I open the fourth window, they would all be fitted squarely.
So, the left panel has a list of 'items' and on right-click I can 'open' them as 'window' (dxDocPanel) on the right. It all appears in dxDocSite.
I was trying to create the mechanism but I just don't know how to.
In image:
1. first stage - only left panel is seen
2. I opened first 'window'
3. second window
4. third window
5. fourth window is opened
This is how I create only left panel:
----
Var
gPanel1: TdxDockPanel;
Begin
FTreeViewFrameCount := 0;
gPanel1 := TdxDockPanel.Create(Self);
gPanel1.DockTo(DxdockSite1 , dtLeft, 0);
CreateFrame(TCodeView_Task s_form, gPanel1); -- THIS IS WHERE I CREATE CONTENT OF THE LEFT PANEL!! - LISTVIEW/TREEVIEW
gPanel1.CaptionButtons := gPanel1.CaptionButtons - [cbClose];
gPanel1.Caption := 'List of windows';
---
Please help.
Thank you
docking.jpg
I need some help with creating 'docking' appearance with ExpressDocking from DevExpress.com. I use TdxDocSite and TdxDockPanel.
I would like to create simple docking application, with one fixed left dxDocPanel which opens new dxDocPanels on the right. Attached image shows that if I open only one new dxDocPanel, it opens it as 'client' aligned, so they both occupy full dxDocSite.
If I open another 'window', it will align both opened as half/half (2. on image) and if three.. they would all be same width to fully occupy dxDocsite and if I open the fourth window, they would all be fitted squarely.
So, the left panel has a list of 'items' and on right-click I can 'open' them as 'window' (dxDocPanel) on the right. It all appears in dxDocSite.
I was trying to create the mechanism but I just don't know how to.
In image:
1. first stage - only left panel is seen
2. I opened first 'window'
3. second window
4. third window
5. fourth window is opened
This is how I create only left panel:
----
Var
gPanel1: TdxDockPanel;
Begin
FTreeViewFrameCount := 0;
gPanel1 := TdxDockPanel.Create(Self);
gPanel1.DockTo(DxdockSite1
CreateFrame(TCodeView_Task
gPanel1.CaptionButtons := gPanel1.CaptionButtons - [cbClose];
gPanel1.Caption := 'List of windows';
---
Please help.
Thank you
docking.jpg
I can imagine some ways of doing this with code but none are particularly simple. The first three are fairly straightforward however the four panel screen adds another layer of complexity. Do you intend to handle more than 4 dynamic panels? If so, some rather complex calculations would be necessary to deal with panels contained in panels contained in panels kind of thing.
ASKER
Well, I believe I would go to max 4 windows opened at one time. More would be very hard to read, since each window has a lot of info shown.
I thought my task is pretty simple, but I'm struggling even with the first two options. Any help would be appreciated.
I thought my task is pretty simple, but I'm struggling even with the first two options. Any help would be appreciated.
As I said. "I can imagine some ways..." I will have to work on it a bit so please be patient
ASKER
SteveBay, I'll wait, any help is appreciated.
This is not nearly complete but it's a pretty good start. I will work to refine it more later.
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, dxDockControl, dxDockPanel, ExtCtrls, StdCtrls,
FileCtrl;
type
TForm2 = class(TForm)
dxDockSite1: TdxDockSite;
DockingMgr: TdxDockingManager;
OpenDialog1: TOpenDialog;
procedure FormCreate(Sender: TObject);
private
DockSite : TdxDockSite;
MainBar : TdxDockPanel;
procedure FileListBoxClick(Sender: TObject);
function GetPanelByCaption(aCaption : String) : TdxDockPanel ;
procedure AddPanel(FileName : string);
procedure DeletePanelByCaption(aCaption : String);
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.FormCreate(Sender: TObject);
var APanel: TdxDockPanel;
FileListBox: TFileListBox;
begin
DockingMgr.Options := DockingMgr.Options + [doFreeOnClose];
DockingMgr.DefaultTabContainerSiteProperties.TabsPosition := tctpTop;
DockingMgr.ViewStyle := vsOffice11;
FileListBox := TFileListBox.Create(Self);
FileListBox.Align := alLeft;
FileListBox.Parent := Self;
FileListBox.Mask := '*.bmp';
FileListBox.ApplyFilePath('C:\Windows');
FileListBox.MultiSelect := True;
FileListBox.OnClick := FileListBoxClick;
dxDockSite1.Align := alClient;
end;
procedure TForm2.FileListBoxClick(Sender: TObject);
var i : Integer;
FileListBox : TFileListBox;
Path : String;
begin
if not (Sender is TFileListBox) then
Exit;
FileListBox := TFileListBox(Sender);
for i := 0 to FileListBox.Count - 1 do
begin
if FileListBox.Selected[i] then
begin
Path := ExtractFilePath(FileListBox.FileName);
if GetPanelByCaption(FileListBox.Items[i] ) = nil then
AddPanel(Path + FileListBox.Items[i]);
end
else begin
DeletePanelByCaption(FileListBox.Items[i]);
end;
end;
end;
procedure TForm2.AddPanel(FileName: string);
var APicture: TPicture;
APanel: TdxDockPanel;
AImage: TImage;
ALastIndex, I: Integer;
begin
// open the file and create the corresponding image object
if not FileExists(FileName) then
Exit;
APicture := TPicture.Create();
APicture.LoadFromFile(FileName);
// create a new panel that will hold the image
APanel := TdxDockPanel.Create(Self);
APanel.Caption := ExtractFileName(FileName);
// dock the panel to the dock site
APanel.DockTo(dxDockSite1, dtLeft, 0);
// create an image control and place it on the panel
AImage := TImage.Create(Self);
AImage.Parent := APanel;
AImage.Align := alClient;
AImage.Center := True;
AImage.Picture := APicture;
end;
function TForm2.GetPanelByCaption(aCaption: String): TdxDockPanel;
var i : integer;
begin
Result := nil;
for i := 0 to dxDockingController.DockControlCount - 1 do
begin
if (dxDockingController.DockControls[i] is TdxDockPanel) and
SameText(TdxDockPanel(dxDockingController.DockControls[i]).Caption,aCaption) then
begin
Result := TdxDockPanel(dxDockingController.DockControls[i]);
break;
end;
end;
end;
procedure TForm2.DeletePanelByCaption(aCaption: String);
var i : Integer;
begin
for i := 0 to dxDockingController.DockControlCount - 1 do
begin
if (dxDockingController.DockControls[i] is TdxDockPanel) and
SameText(TdxDockPanel(dxDockingController.DockControls[i]).Caption,aCaption) then
dxDockingController.DockControls[i].Close;
end;
end;
end.
ASKER
Great! So far, it is exactly what I need.
Getting closer. I still dont have #5. It's a bit more complicated than 1 - 4.
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, dxDockControl, dxDockPanel, ExtCtrls, StdCtrls,
FileCtrl,jpeg ,
CodeSiteLogging ;
type
TForm2 = class(TForm)
dxDockSite1: TdxDockSite;
DockingMgr: TdxDockingManager;
OpenDialog1: TOpenDialog;
procedure FormCreate(Sender: TObject);
private
procedure FileListBoxClick(Sender: TObject);
function GetPanelByCaption(aCaption : String) : TdxDockPanel ;
procedure AddPanel(FileName : string);
procedure DeletePanelByCaption(aCaption : String);
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses Unit3;
{$R *.dfm}
procedure TForm2.FormCreate(Sender: TObject);
var APanel: TdxDockPanel;
FileListBox: TFileListBox;
begin
DockingMgr.Options := DockingMgr.Options + [doFreeOnClose];
DockingMgr.DefaultTabContainerSiteProperties.TabsPosition := tctpTop;
DockingMgr.ViewStyle := vsOffice11;
FileListBox := TFileListBox.Create(Self);
FileListBox.Align := alLeft;
FileListBox.Parent := Self;
FileListBox.Mask := '*.bmp';
FileListBox.ApplyFilePath('C:\Windows');
FileListBox.MultiSelect := True;
FileListBox.OnClick := FileListBoxClick;
//FileListBox.OnDblClick := FileListBoxDblClick;
dxDockSite1.Align := alClient;
end;
procedure TForm2.FileListBoxClick(Sender: TObject);
var i : Integer;
FileListBox : TFileListBox;
Path : String;
bmp : TBitmap;
begin
if not (Sender is TFileListBox) then
Exit;
FileListBox := TFileListBox(Sender);
// Delete existing panels that have been unselected panels first.
for i := 0 to FileListBox.Count - 1 do
begin
if not FileListBox.Selected[i] then
DeletePanelByCaption(FileListBox.Items[i]);
end;
// Add panels that are not found to alread exist.
for i := 0 to FileListBox.Count - 1 do
begin
if FileListBox.Selected[i] then
begin
Path := ExtractFilePath(FileListBox.FileName);
if GetPanelByCaption(FileListBox.Items[i] ) = nil then
AddPanel(Path + FileListBox.Items[i]);
end
end;
end;
procedure TForm2.AddPanel(FileName: string);
var aPicture: TPicture;
aPanel: TdxDockPanel;
aImage: TImage;
I: Integer;
aPanelList : TList;
begin
// open the file and create the corresponding image object
if not FileExists(FileName) then
Exit;
aPanelList := TList.Create;
for i := 0 to dxDockingController.DockControlCount -1 do
begin
if (dxDockingController.DockControls[i] is TdxDockPanel) and
(TdxDockPanel(dxDockingController.DockControls[i]).Tag <> 0) then
aPanelList.Add(dxDockingController.DockControls[i]);
end;
// Don't allow more than four Panels
if aPanelList.Count < 4 then
begin
APicture := TPicture.Create();
APicture.LoadFromFile(FileName);
// create a new panel that will hold the image
APanel := TdxDockPanel.Create(Self);
// Use tag to Identifiy panels WE Created.
aPanel.Tag := aPanelList.Count + 1;
APanel.Caption := ExtractFileName(FileName);
// create an image control and place it on the panel
AImage := TImage.Create(Self);
AImage.Parent := APanel;
AImage.Align := alClient;
AImage.Center := True;
AImage.Picture := APicture;
end;
if aPanelList.Count = 0 then
APanel.DockTo(dxDockSite1, dtClient, maxint)
else if aPanelList.Count = 1 then
begin
APanel.DockTo(dxDockSite1 , dtRight, maxint);
APanel.Width := dxDockSite1.Width div 2;
end
else if aPanelList.Count = 2 then
begin
APanel.DockTo(dxDockSite1, dtRight, maxint);
TdxDockPanel(aPanelList[0]).Width := dxDockSite1.Width div 3;
TdxDockPanel(aPanelList[1]).Width := dxDockSite1.Width div 3;
aPanel.Width := dxDockSite1.Width div 3;
end
else if aPanelList.Count = 3 then
begin
APanel.DockTo(dxDockSite1, dtRight, maxint);
TdxDockPanel(aPanelList[0]).Width := dxDockSite1.Width div 4;
TdxDockPanel(aPanelList[1]).Width := dxDockSite1.Width div 4;
TdxDockPanel(aPanelList[2]).Width := dxDockSite1.Width div 4;
aPanel.Width := dxDockSite1.Width div 4;
APanel.DockTo(dxDockSite1, dtRight, maxint);
end;
aPanelList.Free;
end;
function TForm2.GetPanelByCaption(aCaption: String): TdxDockPanel;
var i : integer;
begin
Result := nil;
for i := 0 to dxDockingController.DockControlCount - 1 do
begin
if (dxDockingController.DockControls[i] is TdxDockPanel) and
SameText(TdxDockPanel(dxDockingController.DockControls[i]).Caption,aCaption) then
begin
Result := TdxDockPanel(dxDockingController.DockControls[i]);
break;
end;
end;
end;
procedure TForm2.DeletePanelByCaption(aCaption: String);
var i : Integer;
begin
for i := dxDockingController.DockControlCount - 1 downto 0 do
begin
if (dxDockingController.DockControls[i] is TdxDockPanel) and
SameText(TdxDockPanel(dxDockingController.DockControls[i]).Caption,aCaption) then
begin
dxDockingController.DockControls[i].Close;
TdxDockPanel(dxDockingController.DockControls[i]).Free;
end;
end;
end;
end.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Awesome! Thank you, very much.