Decade VU-Meter doesn't work correctly


Hi. First of all: Excelent Job.
I have a Problem. I'm using the Decade VU meter in a WFP-Application and aquire Analog-Values.
Increasing the Value works fine, but decreasing doesn't work. The VU-Meter is flickering then and looks scrammbled.
Do you have an Idea? Thank you.
Greets - Helmut


flashx4u wrote May 18, 2010 at 7:32 PM

Hi. I made some fixes and enhancements:
One Problem was that on each value change, all Led's where updated - not only those that are changing.
I integrated a Dictionary that remembers the state of each LED.
I also did a small optimization. Instead of calling the GetTimeline Method every redraw, I get it once after construction and remember it in a dictionary, too.

here is the code:
    /// <summary>
    /// Number of Leds that are in use
    /// </summary>
    private const int NumberOfLeds = 10;

    /// <summary>
    /// Optimization, hold a reference to each storyboard for each LED
    /// </summary>
    private Dictionary<int, Storyboard> _storyBoards = new Dictionary<int, Storyboard>();

    /// <summary>
    /// Remebers the last LED state
    /// </summary>
    private Dictionary<int, bool> _ledStates = new Dictionary<int, bool>();

    /// <summary>
    /// Initializes a new instance of the <see cref="DecadeVuMeter"/> class.
    /// </summary>
    public DecadeVuMeter() {

        // Init the LED states and get the Storyboard references
        for (int i = 0; i < NumberOfLeds; i++) {
            _ledStates[i] = false;
            _storyBoards[i] = GetStoryboard("TimelineLed" + (NumberOfLeds - (i + 1))) as Storyboard;


    /// <summary>
    /// Display the control according the the current value. That means
    /// lighting the necessary LEDS
    /// </summary>
    protected override void Animate() {
        _text.Text = Value.ToString();
        for (int i = 0; i < NumberOfLeds; i++) {
            double pos = ((i + 1) / (double)NumberOfLeds) * 100;
            if ((NormalizedValue * 100) >= pos) {

                // The LED is redrawn only if it's state has changed
                if (!_ledStates[i]) {
                    _ledStates[i] = true; // remember state
            } else {
                // The LED is redrawn only if it's state has changed
                if (_ledStates[i]) {
                    _ledStates[i] = false; // remember state
Again, thanks
Greets - Helmut

flashx4u wrote May 18, 2010 at 9:41 PM

Oh - And I modified the XAML for the MatrixLedCharacter:
I removed the fixed sizeds of the Column and Rowdefinitions and of the control.
Now it's sizeable. I think this should be done to other controls as well.

<db:PlatformIndependentDashboard x:Class="Codeplex.Dashboarding.MatrixLedCharacter"
<Grid x:Name="LayoutRoot" >
    <Grid >

    <Ellipse x:Name="_l0_0" Grid.Row="0" Grid.Column="0" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l1_0" Grid.Row="0" Grid.Column="1" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l2_0" Grid.Row="0" Grid.Column="2" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l3_0" Grid.Row="0" Grid.Column="3" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l4_0" Grid.Row="0" Grid.Column="4" Fill="#FFFD0909"/>

    <Ellipse x:Name="_l0_1" Grid.Row="1" Grid.Column="0" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l1_1" Grid.Row="1" Grid.Column="1" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l2_1" Grid.Row="1" Grid.Column="2" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l3_1" Grid.Row="1" Grid.Column="3" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l4_1" Grid.Row="1" Grid.Column="4" Fill="#FFFD0909"/>

    <Ellipse x:Name="_l0_2" Grid.Row="2" Grid.Column="0" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l1_2" Grid.Row="2" Grid.Column="1" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l2_2" Grid.Row="2" Grid.Column="2" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l3_2" Grid.Row="2" Grid.Column="3" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l4_2" Grid.Row="2" Grid.Column="4" Fill="#FFFD0909"/>

    <Ellipse x:Name="_l0_3" Grid.Row="3" Grid.Column="0" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l1_3" Grid.Row="3" Grid.Column="1" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l2_3" Grid.Row="3" Grid.Column="2" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l3_3" Grid.Row="3" Grid.Column="3" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l4_3" Grid.Row="3" Grid.Column="4" Fill="#FFFD0909"/>

    <Ellipse x:Name="_l0_4" Grid.Row="4" Grid.Column="0" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l1_4" Grid.Row="4" Grid.Column="1" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l2_4" Grid.Row="4" Grid.Column="2" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l3_4" Grid.Row="4" Grid.Column="3" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l4_4" Grid.Row="4" Grid.Column="4" Fill="#FFFD0909"/>

    <Ellipse x:Name="_l0_5" Grid.Row="5" Grid.Column="0" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l1_5" Grid.Row="5" Grid.Column="1" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l2_5" Grid.Row="5" Grid.Column="2" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l3_5" Grid.Row="5" Grid.Column="3" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l4_5" Grid.Row="5" Grid.Column="4" Fill="#FFFD0909"/>

    <Ellipse x:Name="_l0_6" Grid.Row="6" Grid.Column="0" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l1_6" Grid.Row="6" Grid.Column="1" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l2_6" Grid.Row="6" Grid.Column="2" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l3_6" Grid.Row="6" Grid.Column="3" Fill="#FFFD0909"/>
    <Ellipse x:Name="_l4_6" Grid.Row="6" Grid.Column="4" Fill="#FFFD0909"/>


Greets - Helmut

wrote Feb 14, 2013 at 8:10 PM