programing

Flow Layout Panel - 컨트롤의 자동 너비?

abcjava 2023. 5. 31. 14:04
반응형

Flow Layout Panel - 컨트롤의 자동 너비?

FlowLayoutPanel의 FlowLayoutPanel에 삽입된 항목을 FlowLayoutPanel의 자동 크기로 만들 수 있습니까?다음은 예입니다.

1개의 FlowLayoutPanel과 3개의 버튼이 있는 양식:

여기에 이미지 설명 입력

양식 크기를 조정하면 컨트롤은 다음과 같이 나타납니다. "왼쪽에서 오른쪽"으로 정렬됩니다.

여기에 이미지 설명 입력

제가 원하는 것은 다음과 같습니다.컨트롤에는 FlowLayoutPanel의 너비가 있어야 합니다.

여기에 이미지 설명 입력

어떻게 하면 좋을까요?흐름 방향을 바꾸고 앵커 속성을 가지고 놀았지만 운이 없었습니다.

FlowLayoutPanel_Resize 이벤트에서 컨트롤 크기를 조정할 수는 있지만, 약 500개의 사용자 컨트롤을 추가하고 싶습니다. 테스트를 해봤는데 느립니다.

이 경우 하나의 열이 있는 Table Layout Panel을 사용하는 것이 좋습니다.테이블 레이아웃 패널은 FlowLayoutPanel보다 훨씬 예측 가능하고 견고합니다.

FlowLayoutPanel을 계속 사용하려면 첫 번째 컨트롤 너비를 원하는 너비로 설정하고 다른 모든 컨트롤에 대해 Dock = Top을 사용하는 방법도 있습니다.

이것은 간단한 방법입니다.flowLayoutPanel의 SizeChanged 이벤트를 바인딩하고 포함하는 컨트롤의 크기를 조정하기만 하면 됩니다.예:

private void myFlowLayoutPannel_SizeChanged(object sender, EventArgs e)
{
    myFlowLayoutPannel.SuspendLayout();
    foreach (Control ctrl in pnSMS.Controls)
    {
        if (ctrl is Button) ctrl.Width = pnSMS.ClientSize.Width;
    }
    myFlowLayoutPannel.ResumeLayout();
}

StackPanel 클래스가 있습니다.

/// <summary>
/// A stackpanel similar to the Wpf stackpanel.
/// </summary>
public class StackPanel: FlowLayoutPanel
{
    public StackPanel(): base()
    {
        InitializeComponent();
        this.ForceAutoresizeOfControls = true;
    }

    private void InitializeComponent()
    {
        this.SuspendLayout();
        //
        // StackPanel
        //
        this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
        this.WrapContents = false;
        this.ResumeLayout(false);
    }

    /// <summary>
    /// Override it just in order to hide it in design mode.
    /// </summary>
    [Browsable(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public new bool WrapContents
    {
        get { return base.WrapContents; }
        set { base.WrapContents = value; }
    }

    /// <summary>
    /// Override it just in order to set its default value.
    /// </summary>
    [DefaultValue(typeof(AutoSizeMode), "GrowAndShrink")]
    public override AutoSizeMode AutoSizeMode
    {
        get { return base.AutoSizeMode; }
        set { base.AutoSizeMode = value; }
    }

    /// <summary>
    /// Get or set a value that when is true forces the resizing of each control.
    /// If this value is false then only control that have AutoSize == true will be resized to
    /// fit the client size of this container.
    /// </summary>
    [DefaultValue(true)]
    public bool ForceAutoresizeOfControls { get; set; }

    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        this.SuspendLayout();
        switch (FlowDirection)
        {
            case FlowDirection.BottomUp:
            case FlowDirection.TopDown:
                foreach (Control control in this.Controls)
                    if (ForceAutoresizeOfControls || control.AutoSize)
                        control.Width = this.ClientSize.Width - control.Margin.Left - control.Margin.Right;
                break;
            case FlowDirection.LeftToRight:
            case FlowDirection.RightToLeft:
                foreach (Control control in this.Controls)
                    if (ForceAutoresizeOfControls || control.AutoSize)
                        control.Height = this.ClientSize.Height - control.Margin.Top - control.Margin.Bottom;
                break;
            default:
                break;
        }
        this.ResumeLayout();
    }

    protected override void OnLayout(LayoutEventArgs levent)
    {
        base.OnLayout(levent);

        if (levent != null && levent.AffectedControl != null)
        {
            Control control = levent.AffectedControl;
            if (ForceAutoresizeOfControls || control.AutoSize)
            {
                switch (FlowDirection)
                {
                    case FlowDirection.BottomUp:
                    case FlowDirection.TopDown:
                        control.Width = this.ClientSize.Width - control.Margin.Left - control.Margin.Right;
                        break;
                    case FlowDirection.LeftToRight:
                    case FlowDirection.RightToLeft:
                        control.Height = this.ClientSize.Height - control.Margin.Top - control.Margin.Bottom;
                        break;
                    default:
                        break;
                }
            }
        }
    }
}

의 필요성은 없습니다.FlowLayoutPanel여기서.

당신은 당신이 원하는 것을 정상적으로 할 수 있어야 합니다.Panel통제.양식과 함께 늘어나도록 네 면 모두에 고정한 다음 버튼을 추가하여 모두 도킹: 상단으로 설정합니다.

편집 - @UsamaAziz 댓글에 대한 답변입니다.

패널 하단 너머에 숨겨진 컨트롤에 액세스할 수 있도록 하려면 패널의 "자동 스크롤" 속성을 True로 설정합니다.필요한 경우 패널에 수직 스크롤 막대를 추가합니다.

작업 완료.

FlowLayoutPanel는 MSDN에 따라 특정 방식으로 컨트롤을 정렬합니다.

...수직 흐름 방향의 경우 FlowLayoutPanel 컨트롤은 열에서 가장 넓은 하위 컨트롤에서 암시된 열의 너비를 계산합니다.고정 또는 도킹 특성이 있는 이 열의 다른 모든 컨트롤은 이 암시된 열에 맞게 정렬되거나 늘어납니다.이 동작은 수평 흐름 방향에서도 유사한 방식으로 작동합니다.

이상적이지는 않지만 한 자식 컨트롤이 컨테이너와 동일한 너비로 설정되어 있고 나머지 컨트롤이 다음과 같이 설정되어 있으면 기본적으로 이 작업을 수행할 수 있습니다.Dock.

제안합니다...단추의 닻을 가지고 노는 것을 시도합니다...로 설정해 보세요.

Button1.Anchor = (AnchoreStyle.Left or AnchoreStyle.Right)

또는 속성에 설정합니다.

그런 다음 FlowLayoutPanel 대신 Panel 안에 넣습니다.;)

다른 답변에서 언급했듯이 패널 자체로 버튼을 조작하기에 충분합니다.나에게 맞는 코드:

public class ButtonWindow : Panel
{
    public ButtonWindow()
    {
        Dock = DockStyle.Fill;
        AutoScroll = true;

        for (int i = 0; i < 500; i++) 
        {
           Button button = new Button() { Height = 100, Dock = DockStyle.Top };
           Controls.Add(button);
        }
    }
}

좋은 하루 되세요.

언급URL : https://stackoverflow.com/questions/5395754/flowlayoutpanel-automatic-width-for-controls

반응형