Dave's Silverlight Dashboards and gauges

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,
        };
Welcome page

Controls

  • DecadeVuMeter
  • Dial180
  • Dial360
  • DiamondSlider
  • FiveStarRanking
  • MatrixLedMarquee
  • Odometer
  • PerformanceMonitor
  • PlainThermometer
  • ProgressBar
  • RoundLed
  • SixteenSegmentLED
  • TickCross
  • WallThermometer

Bits and pieces

  • Bidirectional operation
  • Contacts and pages
  • Matrix font editor
Designed by Free CSS Templates, Thanks to Dubai Villas