65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.72/5 (14投票s)

2004年5月26日

2分钟阅读

viewsIcon

152739

downloadIcon

3763

一个控件,用于复制音频混音控制台推子/滑块的行为和外观。

Sample Image - avfader.png

引言

最近,我产生了一个想法,需要一个程序能够模拟音频或灯光控制台的某些方面。虽然我可以找到一些控件,可以很好地用于旋钮、刻度和仪表,但我找不到一个看起来像这些控制台上推子控件的滑块控件。

所以,我做了任何自学的程序员在学习一门新语言时会做的事情。我决定开始学习如何用 C# 创建自己的自定义控件。因此,AVFader 控件诞生了。这是我第一次尝试创建自定义控件。我必须说,这种体验并没有我想象的那么糟糕,实际上,创建它非常有趣。

实现

我最初尝试这个控件是尝试扩展 TrackBar 控件,并覆盖 OnPaintWndProc 方法。在与我的一个好朋友 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());
}

结论

总的来说,作为第一次尝试开发控件,我对此非常满意。它完成了我需要它做的事情,而且也没有在我面前爆炸。希望其他人也能发现它有用。

© . All rights reserved.