Sunteți pe pagina 1din 2

Creating a Range Slider in WPF (and

other cool tips and tricks for


UserControls)
I've had to create a RangeSlider (where you can select a range within a range, not just a value)
several times now and there's a couple of neat tricks I use to compose such controls that I thought
I'd share with you.

The idea is simple, the control should look like a slider but with two 'thumbs':

The way I chose to tackle this was, as always, to leverage existing controls wherever possible.
Composition is king in WPF and UserControls provide a very lightweight, cheap angle of attack here.
I decided to have a UserControl composed, primarily, of two Sliders stack on top of each other.
Logically, the RangeSlider would have four properties:

Minimum (double)
LowerValue (double)
UpperValue (double)
Maximum (double)

So the first thing to do is add these as dependency properties to our new UserControl (called
RangeSlider):
public double Minimum
{
get { return (double)GetValue(MinimumProperty); }
set { SetValue(MinimumProperty, value); }
}

public static readonly DependencyProperty MinimumProperty =


DependencyProperty.Register("Minimum", typeof(double), typeof(RangeSlider), new UIPrope
rtyMetadata(0d));

public double LowerValue


{
get { return (double)GetValue(LowerValueProperty); }
set { SetValue(LowerValueProperty, value); }
}

public static readonly DependencyProperty LowerValueProperty =


DependencyProperty.Register("LowerValue", typeof(double), typeof(RangeSlider), new UIPr
opertyMetadata(0d));

public double UpperValue


{
get { return (double)GetValue(UpperValueProperty); }
set { SetValue(UpperValueProperty, value); }
}

public static readonly DependencyProperty UpperValueProperty =


DependencyProperty.Register("UpperValue", typeof(double), typeof(RangeSlider), new UIPr
opertyMetadata(0d));

public double Maximum


{
get { return (double)GetValue(MaximumProperty); }
set { SetValue(MaximumProperty, value); }
}

public static readonly DependencyProperty MaximumProperty =


DependencyProperty.Register("Maximum", typeof(double), typeof(RangeSlider), new UIPrope
rtyMetadata(1d));

Properties Done.

Big trick/tip - using binding to get control data into


your composition
I now need to get these properties into the controls within my UserControl. I use ElementName
binding to this and it looks like this:
<UserControl x:Class="UserControlFun.RangeSlider"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="root">
<Slider x:Name="LowerSlider"
Minimum="{Binding ElementName=root, Path=Minimum}"
Maximum="{Binding ElementName=root, Path=Maximum}"
Value="{Binding ElementName=root, Path=LowerValue}" />
<Slider x:Name="UpperSlider"
Minimum="{Binding ElementName=root, Path=Minimum}"
Maximum="{Binding ElementName=root, Path=Maximum}"
Value="{Binding ElementName=root, Path=UpperValue}" />

</UserControl>

Notice how we set a name on the UserControl which allows us to bind to him and access all his
properties - inluding our juicy new ones. Even, better, because the Bindings are two way any
updates propagate between the UserControl and the composed controls. Awesome. Functionally,
we already have most of our control!
Some rules need applying, e.g. the UpperValue should always be greater than or equal to the
LowerValue and I'd even like one slider to drag the other along if it bumps into it.
However, the most pressing problem at the moment is the fact that my control looks like this:

S-ar putea să vă placă și