滑动面板不工作

Sliding Panel not working

任何人都知道如何创建类似于 Thread 的滑动面板。我正在使用线程,但如果面板包含任何组件,线程看起来会滞后或不流畅。这是我的代码。

public int check, Cstatus = 0;
private void panel1_MouseClick(object sender, MouseEventArgs e)
    {
        if (check == 1 && Cstatus == 1)
        {
            for (int i = 102; i >= 1; i--)
            {
                PanelSubButtons.Size = new Size(i, 403);
                Thread.Sleep(1);

            }
            check = 0; Cstatus = 0;
        }
        else
        {
            if (check == 0)
            {
                PanelSubButtons.Controls.Clear();
                PanelSubButtons.Controls.Add(new SubPanels.PanelResort(this));
                for (int i = 1; i <= 102; i++)
                {
                    PanelSubButtons.Size = new Size(i, 403);
                    Thread.Sleep(1);
                }
                check = 1; Cstatus = 1;
            }
            else if (check == 1)
            {
                for (int i = 102; i >= 1; i--)
                {
                    PanelSubButtons.Size = new Size(i, 403);
                    Thread.Sleep(1);
                }
                PanelSubButtons.Controls.Clear();
                PanelSubButtons.Controls.Add(new SubPanels.PanelResort(this));
                for (int i = 1; i <= 102; i++)
                {
                    PanelSubButtons.Size = new Size(i, 403);
                    Thread.Sleep(1);
                }
                check = 1; Cstatus = 1;
            }
        }
    }

它工作得很好,直到面板内部有一些组件。 我只是问是否有另一种简单的方法可以让您的面板像 Thread.Sleep(1) 一样滑入和滑出;做。

您走在正确的轨道上,因为制作 动画 面板的可能性有很多种,而您的面板就是其中之一。我会提出一些改进建议:

  • 尝试提取重复代码并将其仅放在一个地方
  • 调整组件大小后,refresh/redraw它
  • 尽量不要阻塞主 UI 线程 - 这可以通过使用异步 Task
  • 来实现

考虑到这一点,一个可能的解决方案如下所示:

创建一个控制器 class 可以从中调整 UI 元素(在本例中为面板)的大小和填充(调整大小接受负数以使控件更小和正数使控件更大):

public class ResizingPanelController
{
    public Panel PanelControl { get; private set; }

    public ResizingPanelController()
    {
        this.PanelControl = new Panel();
        // demo - in order to see the panel
        this.PanelControl.BackColor = System.Drawing.Color.LightBlue;
    }

    public void ResizeControl(int delta)
    {
        var y = this.PanelControl.Size.Height;
        System.Threading.Tasks.Task.Factory.StartNew(async () =>
        {
            var x = this.PanelControl.Size.Width;
            // do we need to increase or decrease
            var up = delta > 0;
            // set condition end regarding resize direction (make x bigger or smaller)
            var end = up ? x + delta : x - Math.Abs(delta);
            // evaluate condition regarding resize direction
            Func<int, int, bool> conditionIsMet = (value, limit) => up ? value < limit : value > limit;
            while (conditionIsMet(x, end))
            {
                // increase or decrease x regarding resize direction
                x = up ? x + 1 : x - 1;
                this.PanelControl.Size = new Size(x, y);
                await Task.Delay(10);
                // repaint controls
                this.PanelControl.Refresh();
            }
        }, new System.Threading.CancellationToken(), TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
    }
}

用法:

    public Form1()
    {
        InitializeComponent();
        // create the controller
        var rpc = new ResizingPanelController();
        // add the panel to the form - the form has already two buttons
        this.Controls.Add(rpc.PanelControl);
        // set panel size
        rpc.PanelControl.SetBounds(10, 10, 200, 200);
        // add controls to the panel
        var buttonPlus = new Button();
        var buttonMinus = new Button();
        var label = new Label();
        buttonPlus.Text = "+";
        buttonMinus.Text = "-";
        label.Text = "Something to Show!";
        buttonPlus.SetBounds(1, 1, 50, 25);
        buttonMinus.SetBounds(1, 26, 50, 25);
        label.SetBounds(1, 51, 200, 25);
        rpc.PanelControl.Controls.Add(buttonPlus);
        rpc.PanelControl.Controls.Add(buttonMinus);
        rpc.PanelControl.Controls.Add(label);
        // resize panel
        this.buttonClosePanel.Click += (s, e) =>
            {
                // make it smaller
                rpc.ResizeControl(-170);
            };
        this.buttonOpenPanel.Click += (s, e) =>
        {
            // make it bigger
            rpc.ResizeControl(170);
        };
    }

当面板有一些控件时,在我的机器上调整大小可以顺利进行:

@BenVoight 建议的另一种方法是创建一个 async 方法并为所需的面板元素调用它:

    public Form1()
    {
        InitializeComponent();
        // add controls to the panel
        var buttonPlus = new Button();
        var buttonMinus = new Button();
        var label = new Label();
        buttonPlus.Text = "+";
        buttonMinus.Text = "-";
        label.Text = "Something to Show!";
        buttonPlus.SetBounds(1, 1, 50, 25);
        buttonMinus.SetBounds(1, 26, 50, 25);
        label.SetBounds(1, 51, 200, 25);
        panel1.Controls.Add(buttonPlus);
        panel1.Controls.Add(buttonMinus);
        panel1.Controls.Add(label);
        // resize panel
        this.buttonClosePanel.Click += (s, e) =>
            {
                // make it smaller
                resizeControl(-250);
            };
        this.buttonOpenPanel.Click += (s, e) =>
        {
            // make it bigger
            resizeControl(250);
        };
    }

    private async void resizeControl(int delta)
    {
        var y = panel1.Size.Height;
        var x = this.panel1.Size.Width;
        // do we need to increase or decrease
        var up = delta > 0;
        // set condition end regarding resize direction (make x bigger or smaller)
        var end = up ? x + delta : x - Math.Abs(delta);
        // evaluate condition regarding resize direction
        Func<int, int, bool> conditionIsMet = (value, limit) => up ? value < limit : value > limit;
        while (conditionIsMet(x, end))
        {
            // increase or decrease x regarding resize direction
            x = up ? x + 1 : x - 1;
            this.panel1.Size = new Size(x, y);
            await Task.Delay(10);
            // repaint controls for smooth view
            this.panel1.Refresh();
        }
    }

它的优点是使用起来非常简单,不需要其他 classes 和特殊结构。