音频混音控制台推子/滑块控件






4.72/5 (14投票s)
2004年5月26日
2分钟阅读

152739

3763
一个控件,用于复制音频混音控制台推子/滑块的行为和外观。
引言
最近,我产生了一个想法,需要一个程序能够模拟音频或灯光控制台的某些方面。虽然我可以找到一些控件,可以很好地用于旋钮、刻度和仪表,但我找不到一个看起来像这些控制台上推子控件的滑块控件。
所以,我做了任何自学的程序员在学习一门新语言时会做的事情。我决定开始学习如何用 C# 创建自己的自定义控件。因此,AVFader 控件诞生了。这是我第一次尝试创建自定义控件。我必须说,这种体验并没有我想象的那么糟糕,实际上,创建它非常有趣。
实现
我最初尝试这个控件是尝试扩展 TrackBar
控件,并覆盖 OnPaint
和 WndProc
方法。在与我的一个好朋友 Fadrian 讨论了这种实现的各种缺陷后,他基本上告诉我,从头开始创建一个会更容易。谢天谢地,在快速浏览了 MSDN 文档后,事实证明他是对的。TrackBar
控件有难以置信数量的 Windows 消息进出。
即使我从头开始创建了这个控件,我也尽力使属性尽可能接近 TrackBar
设置,因为尽管该控件外观丑陋,但非常易于使用。理论上,你应该能够将此控件放在现有的 TrackBar
控件之上,而不会有任何麻烦。
设计约束
你可能还记得,我试图复制音频混音控制台上的推子,同时使其尽可能接近 TrackBar
控件。好吧,与任何项目一样,我牺牲了一些功能,有些是由于简单性,有些是由于现实主义的限制。
- 方向始终是垂直的(现实主义)。
- 刻度是线性的,而不是指数的(简单性)。
- 单击滑块轨道不会移动滑块(现实主义)。
- 滑块移动平滑,不会对齐刻度(现实主义)。
在使用此控件时,请考虑这些约束。
代码
这用于在沿轨道拖动滑块时移动滑块图像
private void MoveSlider(int delta)
{
// Move the slider and make sure it stays in the bounds of the control
if (delta < 0 && (this.picSlider.Top + delta) <= 0)
this.picSlider.Top = 0;
else if (delta > 0 && (this.picSlider.Top
+ this.picSlider.Height + delta) >= this.Height)
this.picSlider.Top = this.Height - this.picSlider.Height;
else
this.picSlider.Top += delta;
this.CalculateSliderValue();
}
这用于根据 Value
属性的值移动滑块
private void MoveSlider()
{
// distance between tics used in ratio calc
int distance = Math.Abs(this._maxValue) + Math.Abs(this._minValue);
// percentage of control travelled
float percent = (float)this._value / (float)distance;
// New slider location
this.picSlider.Top = this.Height - this.Top -
Convert.ToInt32(percent * (float)(this.Height - this.picSlider.Height));
}
最后,这个很明确,它根据滑块图像在控件上的位置计算 Value
属性的值
private void CalculateSliderValue() { // distance between tics used in ratio calc int distance = this.Height - this.picSlider.Height; // percentage of control travelled float percent = (float)this.picSlider.Top / (float)distance; // Slider movement in points int movement = Convert.ToInt32(percent * (float)(Math.Abs(this._maxValue) + Math.Abs(this._minValue))); // New value this._value = (this._maxValue >= 0) ? this._maxValue - movement : this._maxValue + movement; // Raise the ValueChanged event ValueChanged(this, new EventArgs()); }
结论
总的来说,作为第一次尝试开发控件,我对此非常满意。它完成了我需要它做的事情,而且也没有在我面前爆炸。希望其他人也能发现它有用。