DelphiのTsplitterとパネルでこの不要な動作を回避するにはどうすればよいですか?
-
27-10-2019 - |
質問
私の問題を示す小さなプロジェクトが含まれています。私は持っています TPageControl
メインフォームに整列しています。 2つのタブシートのそれぞれに、パネルクライアントが揃っています。これらの各パネルには、2つのサブパネルとスプリッターがあります。 LHパネルとスプリッターは左に位置合わせされ、RHパネルがクライアントに配置されています。
基本的に問題は、2つのタブ間の相互作用です。実証するために:
- プログラムを実行します
- メインフォームを水平に伸ばします。パネル3が成長します
- スプリッターを右に移動します。パネル2が成長し、パネル3は10ピクセルの最小幅の制約に縮小します。
- タブシートを選択します2.パネル5は設計どおりで、パネル6はメインフォームが伸びたときに成長しました
- メインフォーム幅を元の幅に減らします。パネル6が縮小しすぎる(望ましくない)
- タブシートをクリックします1.メインフォームの幅がもう一度増加します(望ましくありません)
さて、動作はおそらくアラインされたパネルのルールに関して説明可能ですが、誰かが操作の改善を提案できますか?
unit Unit17;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, ComCtrls;
type
TForm17 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
Panel1: TPanel;
Panel2: TPanel;
Splitter1: TSplitter;
Panel3: TPanel;
Panel4: TPanel;
Splitter2: TSplitter;
Panel5: TPanel;
Panel6: TPanel;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form17: TForm17;
implementation
{$R *.dfm}
end.
object Form17: TForm17
Left = 0
Top = 0
Caption = 'Form17'
ClientHeight = 254
ClientWidth = 314
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object PageControl1: TPageControl
Left = 0
Top = 0
Width = 314
Height = 254
ActivePage = TabSheet1
Align = alClient
Constraints.MinWidth = 30
TabOrder = 0
ExplicitWidth = 480
object TabSheet1: TTabSheet
Caption = 'TabSheet1'
ExplicitWidth = 281
ExplicitHeight = 165
object Panel1: TPanel
Left = 0
Top = 0
Width = 306
Height = 226
Align = alClient
Caption = 'Panel1'
TabOrder = 0
ExplicitWidth = 109
ExplicitHeight = 165
object Splitter1: TSplitter
Left = 151
Top = 1
Width = 12
Height = 224
ExplicitLeft = 145
end
object Panel2: TPanel
Left = 1
Top = 1
Width = 150
Height = 224
Align = alLeft
Caption = 'Panel2'
Constraints.MinWidth = 10
TabOrder = 0
end
object Panel3: TPanel
Left = 163
Top = 1
Width = 142
Height = 224
Align = alClient
Caption = 'Panel3'
Constraints.MinWidth = 10
TabOrder = 1
ExplicitLeft = 141
ExplicitWidth = 330
end
end
end
object TabSheet2: TTabSheet
Caption = 'TabSheet2'
ImageIndex = 1
ExplicitWidth = 281
ExplicitHeight = 165
object Panel4: TPanel
Left = 0
Top = 0
Width = 306
Height = 226
Align = alClient
Caption = 'Panel4'
TabOrder = 0
ExplicitWidth = 109
ExplicitHeight = 165
object Splitter2: TSplitter
Left = 149
Top = 1
Width = 11
Height = 224
ExplicitLeft = 141
end
object Panel5: TPanel
Left = 1
Top = 1
Width = 148
Height = 224
Align = alLeft
Caption = 'Panel5'
Constraints.MinWidth = 10
TabOrder = 0
end
object Panel6: TPanel
Left = 160
Top = 1
Width = 145
Height = 224
Align = alClient
Caption = 'Panel6'
Constraints.MinWidth = 10
TabOrder = 1
ExplicitLeft = 141
ExplicitWidth = 139
ExplicitHeight = 163
end
end
end
end
end
解決
予想される動作を得るには、制約を削除します(MinWidth
)あなたのパネルから。これらの設定は現在です 効果がない とにかく、あなたのスプリッターはaを持っているので MinSize
'30'(デフォルト、保存されていない)。
編集 (コメントへの応答):左側のコントロールのサイズを調整するために、スプリッターの右側にあるコントロールの「細かい」制約を期待することはできません。それは論理的なものであり、制約はあなたが設定した制御のためのプロパティです。あなたが達成するのは、あなたのコントロールがすでにその「分解」にある場合、フォームが縮小することを拒否することです。 望ましくない タブを切り替えると、フォームが大きくなっていることを観察する動作。あなたが望んでいること、あなたはコードに関係する必要があります - マージャンが彼の答えで言ったように。これを達成するための複数の方法があるはずです。たとえば、以下をPanel3の「Oncanresize」イベントに置く必要があります。
procedure TForm1.Panel3CanResize(Sender: TObject; var NewWidth,
NewHeight: Integer; var Resize: Boolean);
begin
if NewWidth < Splitter1.MinSize then
Panel2.Width := Panel2.Width - Splitter1.MinSize + NewWidth;
end;
他のヒント
必ずしも本当の答えではありませんが、いくつかの発言:
minsize voorは、アラフトの並べ替えられたスプリッターが、スプリッターの左右のコントロールに関係しています。パネル6は、実際には、スプリッターのminsize(30)の代わりに、独自のミニ幅(10)にサイズ変更されています。各パネル2、3、5、および6に2つの左アライメントパネルを追加し、10と20の幅と異なる色を与えることで、これをより簡単に実証できます。
Tabsheetを選択して、Mainformの幅を減らした後に再び選択すると、Mainform(Yikes)が成長し、Panel3がスプリッターのminサイズではなく最小幅にも縮小されていることを示しています。
主なフォームのソリューションは、サイズを変更しますか? dunno、しかし、パネルのミニ幅がスプリッターのminsizeと同期していることを確認すると、縮小が削除されます。そして、セルタックが言うように、私はあなたが単にどちらかを選ぶ必要があると思われますが、両方ではありません...
アップデート:
スプリッターのminsizeを30に設定し、パネルのミン幅を0に設定します。メインフォームのサイズ変更を取り除きますが、右側のパネルを0幅に減らします。
スプリッターのminsizeを30に設定し、パネルのminwidthを30に設定すると、最小幅の問題を取り除きますが、メインフォームを変更しました。
パネルのミニ幅を30に設定し、スプリッターのminsizeを1(最小)に設定すると、スプリッターを右に移動し、スプリッターをリリースするときにパネルのミニ幅でメインフォームをサイズすることができます。パネル6が30未満に減少するのを防ぎますが、再びタブ1を再選択するとメインフォームがサイズを変更します。
あなたの最善の策は、スプリッターの分割に頼って、右端に到達したときにスプリッターの動きを制限することにより、右手パネルが遠くまで減少するのを「手動で」防ぐことです。これは、スプリッターのoncanresizeイベントで行うことができます。
ところで、D2009を使用しています
void __fastcall TFMain::SplitterCanResize(TObject *Sender, int &NewSize, bool &Accept)
{
TSplitter *S = (TSplitter *)Sender;
for (int i = 0; Accept && i < S->Parent->ControlCount; i++) if (S->Parent->Controls[i]->Constraints->MaxHeight && S->Parent->Controls[i]->Align == S->Align && NewSize >= S->Parent->Controls[i]->Constraints->MaxHeight * 2) Accept = false;
}
フォームがより広くなっている間、スプリッターを右に遠くまで移動した場合、フォームの幅を減らしたため、左側のパネルよりも狭くなりました(したがって、スプリッターはフォームの外側に自分自身を見つけました)、フォームの動作はどうする必要がありますかこの場合は?あなたは望ましい行動のためのあなたの基準について尋ねられてきました、そして私があなたの答えで私が見ることができるのはあなたの理解だけです 国連望ましい動作。
今、私はパネルとスプリッターを備えたフォームをサイズ変更することの可能性のある副作用で、何度か心配しています。私はそれについてあまり調査しなかったので、特にあなたの状況のような自動復活効果についてはこれまで知りませんでした。とにかく、私が使用していた可能性のある行動のアーティファクトのほとんど(いずれではないにしても)を防ぐために TScrollBox
の代わりにパネルやスプリッターの親のコントロールとして TPanel
.
これは、フォームのサイズ変更を変更して、スクロールボックスのクライアントエリアのサイズ変更に変更されると思います。しかし、私はあなたのケースについて知ることができません。そして、私はこれがあなたの問題の解決策というしてとるというよりも回避策であることを理解しています。