Odometer
Yet another control that belongs at the heart of a car dashboard as well an executive one! The Odometer
is a flexible control with quite a lot of operational options but curently few visual ones.
An Odometer can show between one and ten digits and is based on an Int32 so it has
a maximum of 2,147,483,647. There is no indicator for negative values yet, so it is only usable on natural numbers.
I read the other day that there are 4.4 babies born every second. Our first example shows how many babies have been born
since the Silverlight control loaded. The example shows is an Odometer with an initial value of 0 configured to show 5 digits
and to auto-increment every 0.22 seconds. I also think this is a quite scary example :-)
<db:Odometer
Digits="5"
InitialValue="0"
Interval="0.22"
MeterMode="AutoIncrement" />
|
|
Lets examine the proprties of the Odometer
- Digits
- Sets the number of digits to display
- Will be overridden if the
InitialValue requires more digits
- Is optional for controls with an
InitialValue set (Digits takes preference if it is larger than the number of digits in InitialValue.
- MeterMode (enum)
- AutoIncrement
- Starting from the value of
InitialValue add one to the value of the control every Interval seconds
- Will wrap over after it runs out of digits so if
Digits == 3, then 999 rolls over to 000 and then increments from there
- AutoDecrement
- Starting from the value of
InitialValue subtract one from the value of the control every Interval seconds
- Will wrap over after it runs out of digits so if
Digits == 3 then 000 rolls over to 999 and then decrements from there
- InitialToFinal
- Starting from the value of
InitialValue move one increment/decrement towards FinalValue every Interval seconds
- Stops when it reaches final value
- Decrement or increments Based on which value is the higher (
InitialValue or FinalValue)
- Static
- Sets the InitialValue into the control and doe no further processing
- The user may call the
Odometer functions Increment and Decrement to change the value manually
- This is the mode for your retro page visit counter (go on, I dare ya)
- Interval
- Sets the update freqency in fractional seconds for automatically driven
Odometers (See MeterMode)
Here are a few quick examples, here we are setting the values in XAML you could also set the values in code.
Digits |
<!-- Digits inferred from InitialValue -->
<db:Odometer InitialValue="123" MeterMode="Static" />
<!-- Digits larger than digits in InitialValue, Digits overrides InitialValue -->
<db:Odometer Digits="4" InitialValue="123" MeterMode="Static" />
<!-- Digits less than digits in InitialValue, InitialValue overrides Digits-->
<db:Odometer Digits="3" InitialValue="1234" MeterMode="Static" />
|
|
Autoincrement,AutoDecrement and Interval |
<!-- Start at 1901 and up you go two ticks per second-->
<!-- Because InitialValue has only one digit, we use Digits to force the width-->
<db:Odometer Digits="4" InitialValue="0" MeterMode="AutoIncrement" Interval="0.5"/>
<!-- start at 9999 and start reducing one tick every two seconds-->
<db:Odometer InitialValue="9999" MeterMode="AutoDecrement" Interval="2.0"/>
|
|
InitialToFinal |
<!-- Start at 1901 and up you go to 2001, then stop-->
<db:Odometer InitialValue="1901" FinalValue="2001" MeterMode="InitialToFinal" />
<!-- Start at 2001 and down you go to 1901, then stop-->
<db:Odometer InitialValue="2001" FinalValue="1901" MeterMode="InitialToFinal" />
|
|
Programatic access
|
|
We want to use two buttons to programatically update the Odometer
XAML to declare two buttons and an Odometer
<StackPanel Orientation="Horizontal">
<Button x:Name="up" Width="25" Content="^" Click="up_Click" />
<db:Odometer x:Name="_od" Digits="3" MeterMode="Static" />
<Button x:Name="down" Width="25" Content="v" Click="down_Click"/>
</StackPanel>
Here is the code behind for the two buton click methods
private void up_Click(object sender, RoutedEventArgs e)
{
_od.Increment();
}
private void down_Click(object sender, RoutedEventArgs e)
{
_od.Decrement();
}
Try clicking on the buttons
|
|
|
You arn't just restricted to updating the least significant digit, any digit can be manipulated
The idea behind this is: if you are using a Odomiter as a current score control
in a game, calling increment 1000 times if a mothership is hit would be a pain!
Increment() has an overload that takes an IncrementDecrementDigit that
specifies which digit to increment (list is included at the end of the article)
The markup for the control is
|
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Button x:Name="_inc3" Height="20" Width="40" Content="^" Click="_inc3_Click"/>
<Button x:Name="_inc2" Height="20" Width="40" Content="^" Click="_inc2_Click"/>
<Button x:Name="_inc1" Height="20" Width="40" Content="^" Click="_inc1_Click"/>
</StackPanel>
<db:Odometer x:Name="_od" Digits="3" MeterMode="Static" />
<StackPanel Orientation="Horizontal">
<Button x:Name="_dec3" Height="20" Width="40" Content="v" Click="_dec3_Click"/>
<Button x:Name="_dec2" Height="20" Width="40" Content="v" Click="_dec2_Click"/>
<Button x:Name="_dec1" Height="20" Width="40" Content="v" Click="_dec1_Click"/>
</StackPanel>
</StackPanel>
The code behind for each button click just calls the corresponding Incrememt / Decrement call
private void _inc3_Click(object sender, RoutedEventArgs e){
_od.Increment(Odometer.IncrementDecrementDigit.Hundreds);
}
private void _inc2_Click(object sender, RoutedEventArgs e){
_od.Increment(Odometer.IncrementDecrementDigit.Tens);
}
private void _inc1_Click(object sender, RoutedEventArgs e){
_od.Increment(Odometer.IncrementDecrementDigit.Units);
}
private void _dec3_Click(object sender, RoutedEventArgs e){
_od.Decrement(Odometer.IncrementDecrementDigit.Hundreds);
}
private void _dec2_Click(object sender, RoutedEventArgs e){
_od.Decrement(Odometer.IncrementDecrementDigit.Tens);
}
private void _dec1_Click(object sender, RoutedEventArgs e){
_od.Decrement(Odometer.IncrementDecrementDigit.Units);
}
|
|
Ok, if you read this far and paid attention to the content, scroll back up to the first example and have a look at how many people have been
born since you started reading this. Its quite a sobering fact, unless you manufacture cigars that is :-)
Just for reference here is the defintion of the IncrementDecrementDigit enum
public enum IncrementDecrementDigit
{
/// <summary>
/// Increment the value by 1, the control will automatically roll over if necessary
/// </summary>
Units = 1,
/// <summary>
/// Increment the value by 10, the control will automatically roll over if necessary
/// </summary>
Tens = 2,
/// <summary>
/// Increment the value by 100, the control will automatically roll over if necessary
/// </summary>
Hundreds = 3,
/// <summary>
/// Increment the value by 1000, the control will automatically roll over if necessary
/// </summary>
Thousands = 4,
/// <summary>
/// Increment the value by 10000, the control will automatically roll over if necessary
/// </summary>
TensOfThousands = 5,
/// <summary>
/// Increment the value by 100000, the control will automatically roll over if necessary
/// </summary>
HundredsOfThousands = 6,
/// <summary>
/// Increment the value by 1000000, the control will automatically roll over if necessary
/// </summary>
Millions = 7,
/// <summary>
/// Increment the value by 10000000, the control will automatically roll over if necessary
/// </summary>
TensOfMillions = 8,
/// <summary>
/// Increment the value by 100000000, the control will automatically roll over if necessary
/// </summary>
HundredsOfMillions = 9,
/// <summary>
/// Increment the value by 10000000000, the control will automatically roll over
/// if necessary. Pleas note: We are based on an Int32 at the moment so the tenth
/// digit can only be 0,1 or 2
/// </summary>
Billions = 10,
};