[Description("Very basic slider control with selection range.")]
public partial class SelectionRangeSlider : UserControl
{
[Description("Minimum value of the slider.")]
public Single Min
{
get { return min; }
set { min = value; Invalidate(); }
}
Single min = 0;
[Description("Maximum value of the slider.")]
public Single Max
{
get { return max; }
set { max = value; Invalidate(); }
}
Single max = 100;
[Description("Minimum value of the selection range.")]
public Single SelectedMin
{
get { return selectedMin; }
set
{
selectedMin = value;
if (SelectionChanged != null)
SelectionChanged(this, null);
Invalidate();
}
}
Single selectedMin = 0;
[Description("Maximum value of the selection range.")]
public Single SelectedMax
{
get { return selectedMax; }
set
{
selectedMax = value;
if (SelectionChanged != null)
SelectionChanged(this, null);
Invalidate();
}
}
Single selectedMax = 100;
[Description("Current value.")]
public Single Value
{
get { return value; }
set
{
this.value = value;
if (ValueChanged != null)
ValueChanged(this, null);
Invalidate();
}
}
Single value = 50;
[Description("Fired when SelectedMin or SelectedMax changes.")]
public event EventHandler SelectionChanged;
[Description("Fired when Value changes.")]
public event EventHandler ValueChanged;
public SelectionRangeSlider()
{
InitializeComponent();
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
Paint += new PaintEventHandler(SelectionRangeSlider_Paint);
MouseDown += new MouseEventHandler(SelectionRangeSlider_MouseDown);
MouseMove += new MouseEventHandler(SelectionRangeSlider_MouseMove);
}
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.White);
void SelectionRangeSlider_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Transparent, ClientRectangle);
Rectangle selectionRect = new Rectangle((int)((selectedMin - Min) * Width / (Max - Min)), 0, (int)((selectedMax - selectedMin) * Width / (Max - Min)), Height);
e.Graphics.FillRectangle(Brushes.Blue, selectionRect);
e.Graphics.DrawRectangle(Pens.Black, 0, 0, Width - 1, Height - 1);
e.Graphics.DrawString(SelectedMin.ToString("0.00"), drawFont, drawBrush, ClientRectangle.Left, ClientRectangle.Top);
e.Graphics.DrawString(SelectedMax.ToString("0.00"), drawFont, drawBrush, ClientRectangle.Right - 85, ClientRectangle.Top);
e.Graphics.DrawString(value.ToString("0.00"), drawFont, drawBrush, (ClientRectangle.Left + ClientRectangle.Right) / 2, ClientRectangle.Top);
}
void SelectionRangeSlider_MouseDown(object sender, MouseEventArgs e)
{
Single pointedValue = Min + e.X * (Max - Min) / Width;
Single distValue = Math.Abs(pointedValue - Value);
Single distMin = Math.Abs(pointedValue - SelectedMin);
Single distMax = Math.Abs(pointedValue - SelectedMax);
Single minDist = Math.Min(distValue, Math.Min(distMin, distMax));
if (minDist == distValue)
movingMode = MovingMode.MovingValue;
else if (minDist == distMin)
movingMode = MovingMode.MovingMin;
else
movingMode = MovingMode.MovingMax;
SelectionRangeSlider_MouseMove(sender, e);
}
void SelectionRangeSlider_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
return;
Single pointedValue = Min + e.X * (Max - Min) / Width;
if (movingMode == MovingMode.MovingMax && pointedValue > max)
{
pointedValue = max;
}
if (movingMode == MovingMode.MovingMax && pointedValue < selectedMin + 5)
{
pointedValue = selectedMin + 5;
}
if (movingMode == MovingMode.MovingMin && pointedValue < min)
{
pointedValue = min;
}
if (movingMode == MovingMode.MovingMin && pointedValue > selectedMax - 5)
{
pointedValue = selectedMax - 5;
}
if (movingMode == MovingMode.MovingValue)
Value = (Single)Math.Round(pointedValue, 2);
else if (movingMode == MovingMode.MovingMin)
SelectedMin = (Single)Math.Round(pointedValue, 2);
else if (movingMode == MovingMode.MovingMax)
SelectedMax = (Single)Math.Round(pointedValue, 2);
}
enum MovingMode { MovingValue, MovingMin, MovingMax }
MovingMode movingMode;
}