Click here to Skip to main content
15,868,419 members
Articles / Programming Languages / C# 4.0
Tip/Trick

Multiple Values Slider

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
13 Apr 2013CPOL2 min read 25.7K   448   8   4
Create and use a multiple value slider
Image 1

Introduction

Multiple values slider can be very helpful for creating dynamically gradient brushes with user input.

The slider allows the user to select his own gradient points.

I made it with two classes:

  1. MultiSlider - Type of UserControl. This class manages all the sliders and raises all the events.
  2. MultiSliderPoint - Implements System.ComponentModel.INotifyPropertyChanging and System.ComponentModel.INotifyPropertyChanged interfaces.

This class handles a single slider. It manages the location and style of the slider as well as the sliding event.

Using the Code

MultiSlider

The easiest way to set an items location is in a System.Windows.Controls.Canvas. The canvas allows you to set the left and top of a displayed object just like Windows Forms. I used the MouseKeyUp event to capture a mouse click that wasn't on any of the existing sliders, on that event I added a new slider at the cursor's X value.

I used an System.Collections.ObjectModel.ObservableCollection of MultiSliderPoints in order to manage the current sliders.

MultiSliderPoint

To display the slider, I used a System.Windows.Shapes.Polygon. I added four points in order to create a triangle.

C#
Polygon.Points.Add(new Point(0, 10));
Polygon.Points.Add(new Point(5, 0));
Polygon.Points.Add(new Point(10, 10));
Polygon.Points.Add(new Point(0, 10));

Since the default value of the Polygon's Focusable property is false, you must change it to true in order to allow the selection of the slider.

C#
Polygon.Focusable = true;

The constructor gets the center of the polygon and the canvas to put it in.

C#
public MultiSliderPoint(double center, Panel parent)
{
    this.Parent = parent;
    this.Polygon = new Polygon { Width = defaultWidth, Height = defaultHeight };
    if (parent != null)
        this.Center = center;
    Polygon.Points.Add(new Point(0, 10));
    Polygon.Points.Add(new Point(5, 0));
    Polygon.Points.Add(new Point(10, 10));
    Polygon.Points.Add(new Point(0, 10));
    Polygon.MouseMove += Polygon_MouseMove;
    Polygon.MouseUp += Polygon_MouseUp;
    Polygon.MouseDown += Polygon_Down;
    Polygon.Focusable = true;
}

The slider must know its parent in order to add the polygon and calculate its location.

The sliding is done at the MouseMove event. Easy to do, all you need is just to update the Left value of the polygon with a value relative to the cursor's X value. The problem occurs when the user does a swift motion that slips out of the polygon unintentionally. I solved this problem by capturing the mouse on the MouseDown event and releasing the capture on the MouseUp event.

C#
private void Polygon_MouseMove(object sender, MouseEventArgs e)
{
    if (e.LeftButton != MouseButtonState.Pressed) return;
    var poly = sender as Polygon;
    var point = Mouse.GetPosition(this.Parent);
    var center = point.X;
    if (center >= 0 && center <= this.Parent.Width)
        this.Center = center;
}

private void Polygon_MouseUp(object sender, MouseEventArgs e)
{
    var poly = sender as Polygon;
    poly.ReleaseMouseCapture();
}

private void Polygon_Down(object sender, MouseEventArgs e)
{
    var poly = sender as Polygon;
    poly.CaptureMouse();
    poly.Focus();
}

The capture prevents the mouse from leaving the polygon even though if you look closely, it's not over the polygon.

The center value is calculated as the left value minus half of the polygon width. The left value is implemented as such:

C#
internal double Left
{
    get { return (double)Polygon.GetValue(Canvas.LeftProperty); }
    set
    {
        var changing = value == this.Left;
        if (changing)
            OnPropertyChanging(new System.ComponentModel.PropertyChangingEventArgs("Left"));
        Polygon.SetValue(Canvas.LeftProperty, value);
        if (changing)
            OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("Left"));
    }
}

To handle size changes, I used the System.Windows.Controls.Viewbox. If I didn't use it, I would've needed to calculate the points of the polygon according to the size of the parent as well as calculating the center. The viewbox lets me work in a static size and it handles the rest.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Student
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
BugThe source code appears to be unavailable. Pin
Member 95340664-Jan-13 3:54
Member 95340664-Jan-13 3:54 
GeneralRe: The source code appears to be unavailable. Pin
Kanasz Robert13-Apr-13 1:32
professionalKanasz Robert13-Apr-13 1:32 
QuestionUnable to download the source code. Pin
.NetEnthusiast23-Dec-12 21:45
.NetEnthusiast23-Dec-12 21:45 
AnswerRe: Unable to download the source code. Pin
Kanasz Robert13-Apr-13 1:31
professionalKanasz Robert13-Apr-13 1:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.