DelphiのTsplitterとパネルでこの不要な動作を回避するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/4835617

質問

私の問題を示す小さなプロジェクトが含まれています。私は持っています 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.

これは、フォームのサイズ変更を変更して、スクロールボックスのクライアントエリアのサイズ変更に変更されると思います。しかし、私はあなたのケースについて知ることができません。そして、私はこれがあなたの問題の解決策というしてとるというよりも回避策であることを理解しています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top