2015-02-12 17 views
1

我在運行時生成面板。我在窗體上有一個面板,然後我在裏面有一個滾動框alClient。在該滾動框內,我動態添加面板。它們都屬於Scrollbox,我在生成它們後將它們對齊到底部。所以他們出現在另一個之上。德爾福同步面板順序與表順序

我使用的代碼如下:

Procedure TMain.AdaugaElement(numar:integer; tip:string); 
var 
    pan:TPanel; 
    semn:TShape; 
    pos:TPoint; 
    lab:TLabel; 
    myimg:TImage; 
    bmpsep, dest:TBitmap; 
begin 

    pan:=TPanel.Create(self); 
    pan.Parent:=ScrollBox1; 
    pan.Align:=alBottom; 
    pan.Height:=50; 
    pan.Name:='Layeru'+IntToStr(numar); 
    pan.Caption:='Elementul '+IntToStr(numar); 
    pan.Font.Color:=$00004F4F; 
    pan.Font.Quality:=fqAntialiased; 
    pan.Color:=$0080FFFF; 
    pan.OnMouseDown:=layerRowMouseDown; 
    pan.ParentColor:=false; 
    pan.ParentBackground:=false; 
    pan.Color:=clWhite; 

    Pos:= pan.ClientOrigin; 

    vt.AppendRecord([vt.RecordCount+1,Pan.name,numar,numar,0 ,0, 20,20,800,600,pan.Caption,tip]); 

    lab:=TLabel.Create(self); 
    lab.Parent:=pan; 
    lab.Left:=54; 
    lab.Top:=16; 
    lab.Font.Size:=10; 
    lab.Font.Color:=clBlack; 
    lab.Font.Style:=[]; 
    lab.Font.Quality:=fqAntialiased; 
    lab.Caption:=IntToStr(numar); 
    Randomize; 
    lab.Name:='Layernumber'+IntToStr(numar); 

    semn:=TShape.Create(self); 
    semn.Parent:=pan; 
    semn.Left:=3; 
    semn.Top:=3; 
    semn.Height:=44; 
    semn.Width:=44; 
    semn.Pen.Color:=$00009D9D; 
    semn.Brush.Color:=clWhite; 

    myimg:=TImage.Create(self); 
    myimg.Width:=42; 
    myimg.Height:=42; 
    myimg.Left:=4; 
    myimg.Top:=4; 
    myImg.Visible:=true; 
    myimg.Proportional:=true; 
    myimg.Stretch:=true; 
    myImg.Parent:=pan; 

    SelectLayerPan(numar); 
end; 
  • SelectLayerPan過程模擬所選擇的行中的表,所以當我添加一個新的面板,它顯示爲「選擇」(這是取消選擇'的所有板然後它選擇「新的面板)

  • vtVirtualTable其中我關於所生成的面板輸入信息

所以我添加面板是這樣的:

AdaugaElement(1,'type1'); 
AdaugaElement(2,'type1'); 
AdaugaElement(3,'type1'); 
AdaugaElement(4,'type1'); 

接下來,我想用鼠標來移動它們之間的面板。所以一開始我還補充說:

- panel5 
- panel4 
- panel3 
- panel2 
- panel1 

(按照這個順序)

然後使用鼠標,我拖累PANEL1和panel4和panel5之間拖放。因此,他們將顯示爲:

- panel5 
- **panel1** 
- panel4 
- panel3 
- panel2 

(按照這個順序)

此拖放在layerRowMouseDown完成。

但是,因爲在virtualTable我對面板的信息(在原來的順序),所以

record1: panel1 pos:1 
record2: panel2 pos:2 
record3: panel3 pos:3 
record4: panel4 pos:4 
record5: panel5 pos:5 

我必須確定移動板記錄和更新它,所以它會反映其新的位置,所以VirtualTable必須如下所示:

record1: panel1 pos:4 
record2: panel2 pos:1 
record3: panel3 pos:2 
record4: panel4 pos:3 
record5: panel5 pos:5 

我該怎麼做?

我的意思是,當我放下它時,如何檢測面板結束的位置?或者,也許我該如何獲得他們的容器(ScrollBox1)面板的順序?

到目前爲止,我嘗試使用FindVCLWindow(pos)來確定面板(以及它們在scrollBox中的順序),使用面板的起始位置和倍數,但是當面板更多時,它們不再直接可見(沒有滾動),它顯然停止正常工作。

所以這不是一個解決方案

回答

0

TScrollBox中面板的Top屬性似乎是面板順序的唯一可靠指標。要查找面板的順序,您可以將面板暫時分配給列表,然後在Top屬性中對該列表進行排序。現在,您可以按列表中的順序將它們顯示在滾動框中。

以下是隻是一個臨時列表進行排序的一個例子。您需要修改它以適合您的目的。

procedure TForm6.UpdateRecords; 
var 
    Comparer: IComparer<TMyPanel>; 
    i: integer; 
    s: string; 
begin 
    Comparer := TDelegatedComparer<TMyPanel>.Create(
    function (const A, B: TMyPanel):integer 
    begin 
     Result := A.Top - B.Top; 
    end); 
    TempPanelList := TMyPanelList.Create(Comparer); 
    try 
    for i := 0 to ScrollBox1.ControlCount-1 do 
     TempPanelList.Add(TMyPanel(ScrollBox1.Controls[i])); 
    TempPanelList.Sort; 
    for i := 0 to TempPanelList.Count-1 do 
    begin 
     // replace this with your own code, something like in next snippet 
     s := s + ', ' + inttostr(TempPanelList.items[i].Tag); 
     Label1.Caption := s; 
     // 
    end; 
    finally 
    TempPanelList.Free; 
    end; 
end; 

然後獲得列表中的面板和相應的記錄之間的參考vt,你可以在創建面板的使用tag屬性。你似乎一個參數numar傳遞給AdaugaElement程序,所以假設這可以作爲一個指標工作vt,你可以指定這個numarpan.Tag

最後更新vtpos領域,你可以指定在一個循環中,你分配在TempPanelList的TPanel的指數在vt記錄POS面板的新位置。 注意!我不知道正確的語法與VirtualTable

for i := 0 to TempPanelList.Count-1 do 
begin 
    vt[TPanel(TempPanelList[i]).Tag].pos := i; 
end; 

工作,但您的設置看起來很脆弱的許多賬戶,上面沒有任何幫助的那個。您將分配TMain實例(表單?)作爲所有這些TPanel,TShapes,TLabels和TImages的所有者。當用戶添加和刪除圖層時,它變得非常混亂。相反,我會創建一個組合類TLayerItem來保存與一個圖層相關的所有內容,並且通過一個LayerManager類來管理TLayerItems。

+0

我沒有使用完全相同你的想法,但你的回答讓我感動,我發現我的解決方案。它不使用面板標籤,我使用包含在動態面板中的標籤,以及幫助使用vt(表格)的主要內容。我用過的火花想法是面板的Top屬性排序。萬分感謝 – user1137313 2015-02-13 22:34:16

-2

這似乎是一個低效率的解決方案。另外,爲什麼重新發明輪子?

您所描述的內容與工具欄的工作方式非常相似,只是垂直佈局而非水平佈局。我會看一些工具欄的源代碼,看看你是否不能使用已經設計好的東西去做你想做的事情。如果沒有別的,你會得到一些好的想法如何實施你想要做的事情。

或者,我會考慮使用TFlowPanel的滾動框,你會把你的面板上flowpanel而不是直接到滾動框裏面。

編輯:我向任何人投降了這個道歉,但我們不允許指向異地的東西,我不打算在這裏發佈幾個工具欄組件的所有代碼。

+0

它不重新發明輪子。沒有「輪子」(組件)的行爲,並做我需要做的事情。因此,它是'inventing'車輪,而不是重新發明它 – user1137313 2015-02-13 22:32:05