Здравствуйте, простой вопрос на форме несколько панелей по определенным условиям срываем показываем. Проблема в том, что панели отображаются в хаотичном порядке.
if pnlControlButton.Visible <> Status then begin
if Status then begin
height := height + pnlControlButton.height;
pnlControlButton.Visible := Status;
end else begin
pnlControlButton.Visible := Status;
height := height - pnlControlButton.height;
end
end;
if pnlHistory.Visible <> Status then begin
if Status then begin
height := height + pnlHistory.height;
pnlHistory.Visible := Status;
end else begin
pnlHistory.Visible := Status;
height := height - pnlHistory.height;
end
end;
if pnlInvoiceOffer.Visible <> Status then begin
if Status then begin
height := height + pnlInvoiceOffer.height;
pnlInvoiceOffer.Visible := Status;
end else begin
pnlInvoiceOffer.Visible := Status;
height := height - pnlInvoiceOffer.height;
end
end;
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
05-05-2009 13:08
>>> D7 - да, TFlowPanel что за компонент?
TFlowPanel - компонент с закладки Additional в новых версиях Delphi, в частности, D2006, автоматически выравнивает вставляемые компоненты в порядке, который определяется свойством FlowStyle
Если обходиться без TFlowPanel... Мой опыт показывает, что в случае изменения видимости панелей в рантайме, выравнивание лучше не применять, т.к. возникают проблемы с порядком следования панелей. Решить эту проблему можно, но выглядит это не очень красиво. Лично я не нашёл более подходящего способа, чем прямое выставление координат в цикле (без использования автоматического выравнивания).
Привожу рабочий пример в качестве набора идей, вместе с dfm. Подгонка Left и Width - только для примера, можно для панелей всё как надо выставить в дизайнере и дополнительно включить Anchor по правому краю. Формировать списки тоже можно различными способами.
procedure TForm2.ArrangePanels;
var
i, LastTop: Integer;
begin
LastTop := ClientHeight;
for i := High(FPanels) downto Low(FPanels) do
begin
FPanels[i].Visible := FCheckboxes[i].Checked;
if not FPanels[i].Visible then
Continue;
FPanels[i].Left := 0;
FPanels[i].Width := ClientWidth;
if i = Low(FPanels) then
begin
{Верхняя панель}
FPanels[i].Top := 0;
FPanels[i].Height := LastTop;
Break;
end;
{Нижние панели}
Dec(LastTop, FPanels[i].Height);
FPanels[i].Top := LastTop;
end;
end;
// Назначить всем чекбоксам
procedure TForm2.AnyCheckBoxClick(Sender: TObject);
begin
ArrangePanels;
end;
// Назначить форме
// (автоматически вызывается также при отображении формы)
procedure TForm2.FormResize(Sender: TObject);
begin
ArrangePanels;
end;
end.
Unit2.dfm
object Form2: TForm2
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 494
ClientWidth = 495
Color = clBtnFace
Font.Charset = RUSSIAN_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Arial'
Font.Style = []
OldCreateOrder = False
Position = poDesktopCenter
OnResize = FormResize
PixelsPerInch = 96
TextHeight = 16
object Panel1: TPanel
Left = 50
Top = 20
Width = 350
Height = 240
Caption = 'Panel1'
TabOrder = 0
object Edit1: TEdit
Left = 13
Top = 5
Width = 121
Height = 24
TabOrder = 0
Text = 'Edit1'
end
object CheckBox1: TCheckBox
Left = 13
Top = 47
Width = 97
Height = 17
Caption = 'CheckBox1'
Checked = True
Enabled = False
State = cbChecked
TabOrder = 1
OnClick = AnyCheckBoxClick
end
object CheckBox2: TCheckBox
Left = 13
Top = 80
Width = 97
Height = 17
Caption = 'CheckBox2'
Checked = True
State = cbChecked
TabOrder = 2
OnClick = AnyCheckBoxClick
end
object CheckBox3: TCheckBox
Left = 13
Top = 112
Width = 97
Height = 17
Caption = 'CheckBox3'
Checked = True
State = cbChecked
TabOrder = 3
OnClick = AnyCheckBoxClick
end
object CheckBox4: TCheckBox
Left = 13
Top = 146
Width = 97
Height = 17
Caption = 'CheckBox4'
Checked = True
State = cbChecked
TabOrder = 4
OnClick = AnyCheckBoxClick
end
object CheckBox5: TCheckBox
Left = 13
Top = 179
Width = 97
Height = 17
Caption = 'CheckBox5'
Checked = True
State = cbChecked
TabOrder = 5
OnClick = AnyCheckBoxClick
end
end
object Panel2: TPanel
Left = 50
Top = 261
Width = 350
Height = 41
Caption = 'Panel2'
TabOrder = 1
object Edit2: TEdit
Left = 13
Top = 5
Width = 121
Height = 24
TabOrder = 0
Text = 'Edit2'
end
end
object Panel3: TPanel
Left = 50
Top = 303
Width = 350
Height = 41
Caption = 'Panel3'
TabOrder = 2
object Edit3: TEdit
Left = 13
Top = 5
Width = 121
Height = 24
TabOrder = 0
Text = 'Edit3'
end
end
object Panel4: TPanel
Left = 50
Top = 345
Width = 350
Height = 41
Caption = 'Panel4'
TabOrder = 3
object Edit4: TEdit
Left = 13
Top = 5
Width = 121
Height = 24
TabOrder = 0
Text = 'Edit4'
end
end
object Panel5: TPanel
Left = 50
Top = 387
Width = 350
Height = 41
Caption = 'Panel5'
TabOrder = 4
object Edit5: TEdit
Left = 13
Top = 5
Width = 121
Height = 24
TabOrder = 0
Text = 'Edit5'
end
end
end
>>> Бред - это хлеб на английском, и еще долбанная winda, тракнутый microsoft ))))
А брод - это "широкий"... Главное - выбрать правильный вэй... :)
1. На форме есть несколько панелей с выравниванием вниз. - да
2. Остальное место занимает панель с выравниванием по клиенту. - да
3. Вам нужно часть нижних панелей скрывать и отображать так, чтобы не менялось их взаимное - расположение и порядок обхода. - да
D7 - да, TFlowPanel что за компонент?
Решил как всегда на коленке
т.к. пока все три Панели зависят от Status, то объединил их на одну pnlAll
+ код как по-другому решить я не знаю
if pnlAll.Visible <> Status then begin
pnlAll.Visible := Status;
if Status then begin
pnlAll.align := alTop;
height := height + pnlAll.height;
pnlAll.align := alBottom;
end else
height := height - pnlAll.height;
end;
В этом случаи все нормально, с тремя не стал пробовать не хватило моральных сил
Бред - это хлеб на английском, и еще долбанная winda, тракнутый microsoft ))))
1. На форме есть несколько панелей с выравниванием вниз.
2. Остальное место занимает панель с выравниванием по клиенту.
3. Вам нужно часть нижних панелей скрывать и отображать так, чтобы не менялось их взаимное расположение и порядок обхода.
Если вы используете Delphi выше 7 версии, то я рекомендовал бы обратить внимание на TFlowPanel.
Порядок действий:
1. На форму поместить TFlowPanel
2. Выставить для неё:
AutoWrap = False
FlowStyle = fsTopBottomLeftRight
3. Поместить на эту панель в нужном порядке нижние панели, задать им первоначальную ширину (выравнивание и Anchors в данном случае не работают).
4. Задать для TFlowPanel:
AutoSize = True
Align = alBottom
5. Поместить на форму верхнюю панель и задть ей выравнивание по клиенту.
6. На OnResize формы назначить обработчик, в котором ширину нижних панелей делать равной ClientWidth формы.
После этого все панели будут двигаться как надо, а при скрытии/отображении нижних панелей их взаимное расположение будет сохраняться.
04-05-2009 13:07 | Комментарий к предыдущим ответам
Сергей Дуплик:
>>> А еще проверьте, как выставлены Align у панелей. Если все поставить в одну сторону (скажем, alTop), то должно быть нормально... ВО всяком случае сколько не делал так, всегда работало.
Проблема как раз и состоит в том, что в такой конфигурации при скрытии/отображении панелей меняется их взаимное расположение.
А еще проверьте, как выставлены Align у панелей. Если все поставить в одну сторону (скажем, alTop), то должно быть нормально... ВО всяком случае сколько не делал так, всегда работало.
Мона так, тупо перебираю варианты, (Status - может быть разный для каждой панели)
Суть дело не меняет.
if pnlControlButton.Visible <> Status then begin
pnlControlButton.Visible := Status;
if Status then
height := height + pnlControlButton.height
else
height := height - pnlControlButton.height;
end;
if pnlHistory.Visible <> Status then begin
pnlHistory.Visible := Status
if Status then
height := height + pnlHistory.height
else
height := height - pnlHistory.height;
end;
if pnlInvoiceOffer.Visible <> Status then begin
pnlInvoiceOffer.Visible := Status;
if Status then
height := height + pnlInvoiceOffer.height
else
height := height - pnlInvoiceOffer.height;
end;
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.