滑动面板不工作
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 和特殊结构。
任何人都知道如何创建类似于 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 和特殊结构。