通过单击按钮更改 TGridPanel 中的行顺序
Change the order of rows in TGridPanel by button click
我喜欢通过单击按钮来更改 TGridPanel 中行的顺序。
Gridpanel 行是动态创建的,并包含一个带有手动停靠表单的面板。该表单有自己的编辑组件和一个带有当前行索引的标签。
最好的方法是这样的:
- 通过单击标记该行
- 单击“向上”或“向下”按钮。
- 所选行移动up/down。
- 停靠形式中行的索引发生变化。
这是我的尝试:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
GridPanel1->RowCollection->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn_StepAddClick(TObject *Sender)
{
GridPanel1->RowCollection->BeginUpdate();
if (GridPanel1->RowCollection->Count > 0)
GridPanel1->Height = GridPanel1->Height + 156;
TRowItem * RowItem = GridPanel1->RowCollection->Add();
RowItem->SizeStyle = ssAbsolute;
RowItem->Value = 156;
TPanel * Panel2 = new TPanel(this);
Panel2->Parent = GridPanel1;
Panel2->Color = clWhite;
Panel2->Name = "Panel" + IntToStr(GridPanel1->RowCollection->Count) + "2";
Panel2->Align = alClient;
Panel2->AlignWithMargins = false;
TForm2 * Form2 = new TForm2(this, GridPanel1->RowCollection->Count);
Form2->ManualDock(Panel2, Panel2, alClient);
Form2->Show();
BitBtn_StepDelete->Enabled = true;
GridPanel1->RowCollection->EndUpdate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn_StepDeleteClick(TObject *Sender)
{
// at the moment this button deletes the last row in GridPanel. But it would be fine to select a row by clicking it and delete the selected one.
// After deleting it, the titles of the manually docked forms should change
GridPanel1->RowCollection->BeginUpdate();
GridPanel1->ControlCollection->Delete(GridPanel1->ControlCollection->Count - 1);
GridPanel1->RowCollection->Delete(GridPanel1->RowCollection->Count - 1);
if (GridPanel1->RowCollection->Count > 0)
GridPanel1->Height = GridPanel1->Height - 156;
else
BitBtn_StepDelete->Enabled = false;
GridPanel1->RowCollection->EndUpdate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn_StepInsertClick(TObject *Sender)
{
// Select a row by clicking it and then add a new row before
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn_StepUpClick(TObject *Sender)
{
// Select a row by clicking it and move it up by this button click
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn_StepDownClick(TObject *Sender)
{
// Select a row by clicking it and move it down by this button click
}
//---------------------------------------------------------------------------
有人知道吗?
这是 MoveUp
按钮点击处理程序的 Delphi 实现。它取决于保存当前选定行索引的变量 SelRowId: integer
,如果选择了 none,则为 -1。
它不会移动行,而是将内容(例如面板)从一个单元格移动到另一个单元格。
procedure TForm39.MoveUpBtnClick(Sender: TObject);
var
NewRowId: integer;
begin
GridPanel1.RowCollection.BeginUpdate;
if InRange(SelRowId, 1, GridPanel1.ControlCollection.Count-1) then
begin
NewRowId := SelRowId - 1;
GridPanel1.ControlCollection.ControlItems[0,SelRowId].Row := NewRowId;
SelRowId := NewRowId;
end;
GridPanel1.RowCollection.EndUpdate;
end;
MoveDown
程序在其他方面类似,但SelRowId
的测试是
if InRange(SelRowId, 0, GridPanel1.ControlCollection.Count-2)
而 NewRowId
的赋值是
`NewRowId := SelRowId + 1;`
SelRowId
必须初始化为-1,并在没有选择面板时设置为-1。
我假设在我的测试应用程序中单击面板...
// Clicking a panel
// - deselects the panel if it was previously selected
// - deselects any other previously selected panel in preparation to:
// - selects the panel if it was not previously selected
在我的测试应用程序中,我分两步获得选定的面板行:
通过ControlCollection.IndexOf(panel)
获取面板索引
从 ControlCollection[indx] 中获取行
var
indx: integer;
Panel: TPanel;
Panel := Sender as TPanel;
{...}
indx := TGridPanel(Panel.Parent).ControlCollection.IndexOf(Panel);
SelRowId := TGridPanel(Panel.Parent).ControlCollection[indx].Row;
我的测试项目的完整实现在这里:
implementation
{$R *.dfm}
uses Math;
procedure TForm39.FormCreate(Sender: TObject);
begin
SelRowId := -1;
end;
procedure TForm39.MoveUpBtnClick(Sender: TObject);
var
NewRowId: integer;
begin
GridPanel1.RowCollection.BeginUpdate;
if InRange(SelRowId, 1, GridPanel1.ControlCollection.Count-1) then
begin
NewRowId := SelRowId - 1;
GridPanel1.ControlCollection.ControlItems[0,SelRowId].Row := NewRowId;
SelRowId := NewRowId;
end;
GridPanel1.RowCollection.EndUpdate;
end;
procedure TForm39.MoveDnBtnClick(Sender: TObject);
var
NewRowId: integer;
begin
GridPanel1.RowCollection.BeginUpdate;
if InRange(SelRowId, 0, GridPanel1.ControlCollection.Count-2) then
begin
NewRowId := SelRowId + 1;
GridPanel1.ControlCollection.ControlItems[0,SelRowId].Row := NewRowId;
SelRowId := NewRowId;
end;
GridPanel1.RowCollection.EndUpdate;
end;
procedure TForm39.AddStepBtnClick(Sender: TObject);
var
NewRow: TRowItem;
P: Tpanel;
begin
GridPanel1.RowCollection.BeginUpdate;
NewRow := GridPanel1.RowCollection.Add;
GridPanel1.Height := GridPanel1.Height + 50;
NewRow.SizeStyle := ssAbsolute;
NewRow.Value := 50;
P := Tpanel.Create(self);
P.Caption := 'Panel '+IntToStr(GridPanel1.RowCollection.Count);
P.Align := alClient;
P.AlignWithMargins := False;
P.Parent := GridPanel1;
P.ParentBackground := False;
P.ParentColor := False;
P.Color := Random(256) shl 16 + Random(256) shl 8 + Random(256);
P.OnClick := PanelClick;
GridPanel1.RowCollection.EndUpdate;
end;
// Clicking a panel
// - selects the panel if it was not previously selected
// - deselects the panel if it was previously selected
// - deselects any other previously selected panel
procedure TForm39.PanelClick(Sender: TObject);
var
indx: integer;
Panel: TPanel;
begin
Panel := Sender as TPanel;
// previously selected panel
if Assigned(SelPanel) then
SelPanel.Color := SavedColor; // reset its color
if SelPanel = Panel then // a second click unselects
begin
SelPanel := nil;
SelRowId := -1;
Exit;
end;
SavedColor := Panel.Color; // save newly selected panels color
Panel.Color := clRed; // set selected color
SelPanel := Panel; // set selected panel
indx := TGridPanel(Panel.Parent).ControlCollection.IndexOf(Panel);
SelRowId := TGridPanel(Panel.Parent).ControlCollection[indx].Row;
end;
我喜欢通过单击按钮来更改 TGridPanel 中行的顺序。 Gridpanel 行是动态创建的,并包含一个带有手动停靠表单的面板。该表单有自己的编辑组件和一个带有当前行索引的标签。 最好的方法是这样的:
- 通过单击标记该行
- 单击“向上”或“向下”按钮。
- 所选行移动up/down。
- 停靠形式中行的索引发生变化。
这是我的尝试:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
GridPanel1->RowCollection->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn_StepAddClick(TObject *Sender)
{
GridPanel1->RowCollection->BeginUpdate();
if (GridPanel1->RowCollection->Count > 0)
GridPanel1->Height = GridPanel1->Height + 156;
TRowItem * RowItem = GridPanel1->RowCollection->Add();
RowItem->SizeStyle = ssAbsolute;
RowItem->Value = 156;
TPanel * Panel2 = new TPanel(this);
Panel2->Parent = GridPanel1;
Panel2->Color = clWhite;
Panel2->Name = "Panel" + IntToStr(GridPanel1->RowCollection->Count) + "2";
Panel2->Align = alClient;
Panel2->AlignWithMargins = false;
TForm2 * Form2 = new TForm2(this, GridPanel1->RowCollection->Count);
Form2->ManualDock(Panel2, Panel2, alClient);
Form2->Show();
BitBtn_StepDelete->Enabled = true;
GridPanel1->RowCollection->EndUpdate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn_StepDeleteClick(TObject *Sender)
{
// at the moment this button deletes the last row in GridPanel. But it would be fine to select a row by clicking it and delete the selected one.
// After deleting it, the titles of the manually docked forms should change
GridPanel1->RowCollection->BeginUpdate();
GridPanel1->ControlCollection->Delete(GridPanel1->ControlCollection->Count - 1);
GridPanel1->RowCollection->Delete(GridPanel1->RowCollection->Count - 1);
if (GridPanel1->RowCollection->Count > 0)
GridPanel1->Height = GridPanel1->Height - 156;
else
BitBtn_StepDelete->Enabled = false;
GridPanel1->RowCollection->EndUpdate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn_StepInsertClick(TObject *Sender)
{
// Select a row by clicking it and then add a new row before
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn_StepUpClick(TObject *Sender)
{
// Select a row by clicking it and move it up by this button click
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn_StepDownClick(TObject *Sender)
{
// Select a row by clicking it and move it down by this button click
}
//---------------------------------------------------------------------------
有人知道吗?
这是 MoveUp
按钮点击处理程序的 Delphi 实现。它取决于保存当前选定行索引的变量 SelRowId: integer
,如果选择了 none,则为 -1。
它不会移动行,而是将内容(例如面板)从一个单元格移动到另一个单元格。
procedure TForm39.MoveUpBtnClick(Sender: TObject);
var
NewRowId: integer;
begin
GridPanel1.RowCollection.BeginUpdate;
if InRange(SelRowId, 1, GridPanel1.ControlCollection.Count-1) then
begin
NewRowId := SelRowId - 1;
GridPanel1.ControlCollection.ControlItems[0,SelRowId].Row := NewRowId;
SelRowId := NewRowId;
end;
GridPanel1.RowCollection.EndUpdate;
end;
MoveDown
程序在其他方面类似,但SelRowId
的测试是
if InRange(SelRowId, 0, GridPanel1.ControlCollection.Count-2)
而 NewRowId
的赋值是
`NewRowId := SelRowId + 1;`
SelRowId
必须初始化为-1,并在没有选择面板时设置为-1。
我假设在我的测试应用程序中单击面板...
// Clicking a panel
// - deselects the panel if it was previously selected
// - deselects any other previously selected panel in preparation to:
// - selects the panel if it was not previously selected
在我的测试应用程序中,我分两步获得选定的面板行:
通过
获取面板索引ControlCollection.IndexOf(panel)
从 ControlCollection[indx] 中获取行
var
indx: integer;
Panel: TPanel;
Panel := Sender as TPanel;
{...}
indx := TGridPanel(Panel.Parent).ControlCollection.IndexOf(Panel);
SelRowId := TGridPanel(Panel.Parent).ControlCollection[indx].Row;
我的测试项目的完整实现在这里:
implementation
{$R *.dfm}
uses Math;
procedure TForm39.FormCreate(Sender: TObject);
begin
SelRowId := -1;
end;
procedure TForm39.MoveUpBtnClick(Sender: TObject);
var
NewRowId: integer;
begin
GridPanel1.RowCollection.BeginUpdate;
if InRange(SelRowId, 1, GridPanel1.ControlCollection.Count-1) then
begin
NewRowId := SelRowId - 1;
GridPanel1.ControlCollection.ControlItems[0,SelRowId].Row := NewRowId;
SelRowId := NewRowId;
end;
GridPanel1.RowCollection.EndUpdate;
end;
procedure TForm39.MoveDnBtnClick(Sender: TObject);
var
NewRowId: integer;
begin
GridPanel1.RowCollection.BeginUpdate;
if InRange(SelRowId, 0, GridPanel1.ControlCollection.Count-2) then
begin
NewRowId := SelRowId + 1;
GridPanel1.ControlCollection.ControlItems[0,SelRowId].Row := NewRowId;
SelRowId := NewRowId;
end;
GridPanel1.RowCollection.EndUpdate;
end;
procedure TForm39.AddStepBtnClick(Sender: TObject);
var
NewRow: TRowItem;
P: Tpanel;
begin
GridPanel1.RowCollection.BeginUpdate;
NewRow := GridPanel1.RowCollection.Add;
GridPanel1.Height := GridPanel1.Height + 50;
NewRow.SizeStyle := ssAbsolute;
NewRow.Value := 50;
P := Tpanel.Create(self);
P.Caption := 'Panel '+IntToStr(GridPanel1.RowCollection.Count);
P.Align := alClient;
P.AlignWithMargins := False;
P.Parent := GridPanel1;
P.ParentBackground := False;
P.ParentColor := False;
P.Color := Random(256) shl 16 + Random(256) shl 8 + Random(256);
P.OnClick := PanelClick;
GridPanel1.RowCollection.EndUpdate;
end;
// Clicking a panel
// - selects the panel if it was not previously selected
// - deselects the panel if it was previously selected
// - deselects any other previously selected panel
procedure TForm39.PanelClick(Sender: TObject);
var
indx: integer;
Panel: TPanel;
begin
Panel := Sender as TPanel;
// previously selected panel
if Assigned(SelPanel) then
SelPanel.Color := SavedColor; // reset its color
if SelPanel = Panel then // a second click unselects
begin
SelPanel := nil;
SelRowId := -1;
Exit;
end;
SavedColor := Panel.Color; // save newly selected panels color
Panel.Color := clRed; // set selected color
SelPanel := Panel; // set selected panel
indx := TGridPanel(Panel.Parent).ControlCollection.IndexOf(Panel);
SelRowId := TGridPanel(Panel.Parent).ControlCollection[indx].Row;
end;