我们有时候需要设计一个比重设置,当然几个比重合计之和肯定要100%,就这么一个简单的需求,换成是你,你会如何设计?个数不确定,另一个则是要保证100%。设计这样的方案困扰了我好几天,最开始设计了几个下拉框,但因操作不方便被痛批好几次,我不知道有没现成的资源可用,山穷水尽后想到TrackBar控件,虽然不能说这是最好的,但起码操作起来还算方便,多个TrackBar联动控制最大的难点在于如何保证几个TrackBar的值之和为100%
我的思路是这样:滑动前面的滑块会对后面的几个产生影响,而且后面几个的值只能平均分配;但当滑动后面的滑块则对前面的没有任何影响,否则将陷入“死循环”,不多说了,先上最终效果图
我这里设计了一个UserControl,里面放置三个控件:GroupBox/Label/TrackBar,Label用来显示当前百分比,GroupBox用来显示标签,外部可以通过这个标签来获取当前的百分比,下面是UserControl源代码
public partial class UserControl1 : UserControl
{
/// <summary>
/// 标签
/// </summary>
public string UCName
{
get { return groupBox1.Text; }
set { groupBox1.Text = value; }
}
/// <summary>
/// 刻度值
/// </summary>
public int TickValue
{
get { return trackBar1.Value; }
set {
trackBar1.Value = value;
label1.Text = string.Format("{0}%", trackBar1.Value);
}
}
//声明事件委托
public delegate void MyScrollHandler(object sender);
//定义事件
public event MyScrollHandler OnTrackBar_Scroll;
public UserControl1()
{
InitializeComponent();
label1.Text = string.Format("{0}%", trackBar1.Value);
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
if (OnTrackBar_Scroll != null)
{
OnTrackBar_Scroll(this);
label1.Text = string.Format("{0}%", trackBar1.Value);
}
}
}
主界面源代码
/// <summary>
/// TrackBar数量
/// </summary>
int tbCount = 4;
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
ArrayList al = new ArrayList();
for (int i = 1; i <= tbCount; i++)
{
UserControl1 uc = new UserControl1();
uc.UCName = "TrackBar" + i;
uc.TickValue = 100 / tbCount; //默认平均数
uc.Tag = i; //标识第几个
uc.Dock = DockStyle.Top;
uc.OnTrackBar_Scroll += new UserControl1.MyScrollHandler(uc_OnTrackBar_Scroll);
al.Add(uc);
}
al.Reverse(); //反序使得UC按标识顺序添加到容器上
foreach (UserControl1 uc in al)
{
this.panel1.Controls.Add(uc);
}
}
/// <summary>
/// 滑块联动控制(核心)
/// </summary>
/// <param name="sender"></param>
private void uc_OnTrackBar_Scroll(object sender)
{
int leftPct = 100;
UserControl1 uc = sender as UserControl1;
int tag = Convert.ToInt32(uc.Tag);
for (int i = 0; i < tbCount; i++)
{
UserControl1 ucc = this.panel1.Controls[(tbCount - 1) - i] as UserControl1;
int t = Convert.ToInt32(ucc.Tag);
if (t > tag) //后面几个的百分比平均分配
{
ucc.TickValue = leftPct / (tbCount - tag);
}
else //获取剩余百分比
{
leftPct -= ucc.TickValue;
if (leftPct <= 0 && t == tag) //当前滑块,控制剩余百分比不小于0
{
ucc.TickValue += leftPct;
leftPct = 0;
}
}
}
}