Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Docking issue with DevExpress's ExpressDocking library

Posted on 2009-05-19
9
Medium Priority
?
1,667 Views
Last Modified: 2012-05-07
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_Tasks_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
0
Comment
Question by:Delphi_developer
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 14

Expert Comment

by:SteveBay
ID: 24436774
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.
0
 

Author Comment

by:Delphi_developer
ID: 24437581
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.
0
 
LVL 14

Expert Comment

by:SteveBay
ID: 24437726
As I said. "I can imagine some ways..." I will have to work on it a bit so please be patient
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:Delphi_developer
ID: 24438980
SteveBay, I'll wait, any help is appreciated.
0
 
LVL 14

Expert Comment

by:SteveBay
ID: 24443100
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.

Open in new window

0
 

Author Comment

by:Delphi_developer
ID: 24444297
Great! So far, it is exactly what I need.
0
 
LVL 14

Expert Comment

by:SteveBay
ID: 24453055
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.

Open in new window

0
 
LVL 14

Accepted Solution

by:
SteveBay earned 2000 total points
ID: 24454165
This is it! I suppose it's likely that there are more efficient ways of doing this but I'm exhausted.:-)
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
 
{$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;
     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;
 
     // Find panels we created and add then to a list.
     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
          // fill client area with 1
          APanel.DockTo(dxDockSite1, dtClient, maxint)
     else if aPanelList.Count = 1 then
          begin
          // arrange 2 side by side
          APanel.DockTo(dxDockSite1 , dtRight, maxint);
          APanel.Width := dxDockSite1.Width div 2;
          end
     else if aPanelList.Count = 2 then
          begin
          // Arrange 3 side by side by side
          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
          // Arrange 4 - 2 over 2
          APanel.DockTo(dxDockSite1, dtRight, maxint);
          TdxDockPanel(aPanelList[0]).Width := dxDockSite1.Width div 2;
          TdxDockPanel(aPanelList[1]).DockTo(TdxDockPanel(aPanelList[0]),dtBottom, MaxInt);
          TdxDockPanel(aPanelList[0]).Height := dxDockSite1.Height div 2;
          TdxDockPanel(aPanelList[2]).Width := dxDockSite1.Width div 2;
          APanel.DockTo(TdxDockPanel(aPanelList[2]), dtBottom, MaxInt);
          TdxDockPanel(aPanelList[2]).Height := dxDockSite1.Height div 2;
          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.

Open in new window

0
 

Author Comment

by:Delphi_developer
ID: 24457261
Awesome! Thank you, very much.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Suggested Courses

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question