0

フレームをフロー パネルに動的に入力しています (水平方向の VCL Metropolis アプリの一部として)。すべての項目が水平方向に収まるように、各グループのフロー パネルのサイズを変更する必要があります。私は時々トリックを行う非常に単純な式を持っていますが、常にではありません-特に奇数のアイテムを追加する場合。フロー パネルのは、2 つのフレームが垂直に収まるFlowStyleように設定されています。fsTopBottomLeftRight

たとえば、7 つのアイテムを追加すると、正しい幅 (横方向に 4 つのアイテム) が自動的に検出されます。ただし、5 つのアイテムを追加しても正しい幅が検出されません (横方向に 3 であるはずですが、横方向に 2 つ検出されてしまいます)。

各グループの幅を正しく計算するにはどうすればよいですか?

各アイテム グループにアイテムを追加する手順は次のとおりです (無関係なものをいくつか削除しています)。

procedure TSplitForm.LoadScreen;
const
  FRAME_WIDTH = 170;    //Width of each frame
  FRAME_HEIGHT = 250;   //Height of each frame
  FRAME_MARGIN = 30;    //Margin to right of each group
  FRAME_VERT_COUNT = 2; //Number of frames vertically stacked
var
  CurGroup: TFlowPanel; //Flow panel currently being populated
  procedure ResizeGroup(FP: TFlowPanel);
  var
    Count, CountHalf, NewWidth, I: Integer;
  begin
    //Resize the specific flow panel's width to fit all items
    Count:= FP.ComponentCount;
    NewWidth:= FRAME_WIDTH + FRAME_MARGIN;  //Default width if no items
    if Count > 0 then begin
      //THIS IS WHERE MY CALCULATIONS DO NOT WORK
      CountHalf:= Round(Count / FRAME_VERT_COUNT);
      NewWidth:= (CountHalf * FRAME_WIDTH) + FRAME_MARGIN;
    end;
    if FP.Parent.Width <> NewWidth then
      FP.Parent.Width:= NewWidth;
    //Resize main flow panel's width to fit all contained group panels
    //(automatically extends within scroll box to extend scrollbar)
    Count:= TFlowPanel(FP.Parent.Parent).ControlCount;
    NewWidth:= 0;
    for I := 0 to Count-1 do begin
      NewWidth:= NewWidth + FP.Parent.Parent.Controls[I].Width;
    end;
    NewWidth:= NewWidth + FRAME_MARGIN;
    if FP.Parent.Parent.Width <> NewWidth then
      FP.Parent.Parent.Width:= NewWidth;
  end;
  procedure Add(const Name, Title, Subtitle: String);
  var
    Frame: TfrmItemFrame;
  begin
    Frame:= AddItemFrame(CurGroup, Name); //Create panel, set parent and name
    Frame.OnClick:= ItemClick;
    Frame.Title:= Title;
    Frame.Subtitle:= Subtitle;
    ResizeGroup(CurGroup);
  end;
begin
  CurGroup:= fpMainGroup;
  Add('boxMainItem1', 'Item 1', 'This is item 1');
  Add('boxMainItem2', 'Item 2', 'This is item 2');
  Add('boxMainItem3', 'Item 3', 'This is item 3');
  Add('boxMainItem4', 'Item 4', 'This is item 4');
  Add('boxMainItem5', 'Item 5', 'This is item 5');

  CurGroup:= fpInventoryGroup;
  Add('boxInventItem1', 'Item 1', 'This is item 1');
  Add('boxInventItem2', 'Item 2', 'This is item 2');
  Add('boxInventItem3', 'Item 3', 'This is item 3');
  Add('boxInventItem4', 'Item 4', 'This is item 4');
  Add('boxInventItem5', 'Item 5', 'This is item 5');
  Add('boxInventItem6', 'Item 6', 'This is item 6');
  Add('boxInventItem7', 'Item 7', 'This is item 7');
end;

これは、そのコードが生成するもののスクリーンショットです。

アイテム幅のスクリーンショット

ご覧のとおり、5 つのアイテムを含む最初のグループは 5 番目のアイテムを非表示にしていますが、7 つのアイテムを含む 2 番目のグループは 7 つすべてを問題なく表示しています。

親子関係の構造は次のようになります (問題のあるフロー パネルは太字で示されています)。

  • SplitForm: TSplitForm (メイン フォーム)
    • ScrollBox2: TScrollBox (メイン フロー パネルのコンテナ)
      • fpMain: TFlowPanel (すべてのグループ パネルのコンテナ)
        • pMainGroup: TPanel (フロー パネルとタイトル パネルのコンテナ)
          • fpMainGroup : TFlowPanel (額縁のコンテナ)
          • pMainGroupTitle: TPanel (グループの一番上のタイトル)
        • pInventoryGroup: TPanel (フロー パネルとタイトル パネルのコンテナ)
          • fpInventoryGroup : TFlowPanel (額縁のコンテナ)
          • pInventoryGroupTitle: TPanel (グループの一番上のタイトル)
        • (より多くのグループのための他のパネル)

各フロー パネルのAutoSizeプロパティを使用してみましたが、高さ (2 つ上) を認識せず、事態はさらに悪化しました。基本的に、これらのフロー パネル内の列の総数を適切に検出する必要があるだけです。

4

2 に答える 2

3
Round(Count / FRAME_VERT_COUNT);

ここFRAME_VERT_COUNTにあり2ます。あなたの表情Countはいつ5

Rount(2.5);

デフォルトの丸めモードはバンカー丸めで、これは に評価され2ます。式はいつCountですか7

Round(3.5); 

バンカーの丸めは、これが であることを意味します4

Sertacが提案して使用することを行うことができますceil。ただし、浮動小数点を完全に避けるだけです。それは必要ないだけであり、一般的な規則として、実行可能な場合は常に整数演算が優先されます。あなたの表現は

(Count + FRAME_VERT_COUNT - 1) div FRAME_VERT_COUNT
于 2014-11-23T22:46:50.850 に答える
2

部分的なタイルは必要ないため、必要な列数を計算するときは、最も近い (等しいかそれ以上の) 整数が必要です。

デフォルトの丸めモードでRound(7/2)は、'4' です。それはいいです。ただしRound(5/2)「2」です。その理由は

デフォルトの丸めモード (rmNearest) では、X が 2 つの整数のちょうど中間にある場合、結果は常に偶数になります。

行が 2 つしかない場合は、切り上げで解決できます (除算は常に整数か、2 つの整数の間の数値になります)。一般的な解決策としては、 を使用することをお勧めしますCeil

于 2014-11-23T22:39:43.467 に答える