滑动面板不工作

时间:2015-01-03 17:28:27

标签: c# winforms

任何人都知道如何创建类似于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)相同的方式滑入和滑出;做。

1 个答案:

答案 0 :(得分:3)

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

  • 尝试仅在一个地方提取并放置重复的代码
  • 调整组件大小后,刷新/重绘
  • 尽量不阻止主UI线程 - 这可以通过例如使用异步Task
  • 来实现

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

创建一个控制器类,UI元素(在本例中为Panel)可以调整大小并填充(调整大小时加上负数以使控件更小而正数可以使控件更大):

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);
        };
    }

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

enter image description here

@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();
        }
    }

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