The five minute gauge control for WinRT/XAML

Wow, gauge controls are pretty easy to implement. Why would anyone pay for one? πŸ™‚

This one took me literally 5 minutes. True, it is just a UserControl and it only shows 0-360 values I needed to debug some compass code, but it’s easy to build on it so I thought I’d share it since all my other blog post ideas need quite a bit more time than 5 minutes… πŸ™‚

gauges

XAML

<UserControl
    x:Class="App98.SimpleGauge"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App98"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400"
    Width="200"
    Height="200"
    IsHitTestVisible="False"
    x:Name="root">
    
    <Grid
        DataContext="{Binding ElementName=root}">
        <Ellipse
            Opacity="0.5"
            Fill="WhiteSmoke"
            Stretch="Fill"/>
        <Grid
            Margin="1">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock
                Text="{Binding ValueString}"
                Foreground="Gray"
                Grid.Row="1"
                Grid.ColumnSpan="2"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"/>
            <Line
                HorizontalAlignment="Right"
                VerticalAlignment="Stretch"
                Stretch="Fill"
                Stroke="Red"
                StrokeThickness="2"
                X1="0"
                Y1="0"
                X2="0"
                Y2="1"
                RenderTransformOrigin="0,1">
                <Line.RenderTransform>
                    <RotateTransform
                        Angle="{Binding Value}"/>
                </Line.RenderTransform>
            </Line>
        </Grid>
    </Grid>
</UserControl>

Code behind:

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace App98
{
    public sealed partial class SimpleGauge : UserControl
    {
        #region Value
        /// <summary>
        /// Value Dependency Property
        /// </summary>
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register(
                "Value",
                typeof(double),
                typeof(SimpleGauge),
                new PropertyMetadata(0d, OnValueChanged));

        /// <summary>
        /// Gets or sets the Value property. This dependency property 
        /// indicates ....
        /// </summary>
        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        /// <summary>
        /// Handles changes to the Value property.
        /// </summary>
        /// <param name="d">
        /// The <see cref="DependencyObject"/> on which
        /// the property has changed value.
        /// </param>
        /// <param name="e">
        /// Event data that is issued by any event that
        /// tracks changes to the effective value of this property.
        /// </param>
        private static void OnValueChanged(
            DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = (SimpleGauge)d;
            double oldValue = (double)e.OldValue;
            double newValue = target.Value;
            target.OnValueChanged(oldValue, newValue);
        }

        /// <summary>
        /// Provides derived classes an opportunity to handle changes
        /// to the Value property.
        /// </summary>
        /// <param name="oldValue">The old Value value</param>
        /// <param name="newValue">The new Value value</param>
        private void OnValueChanged(
            double oldValue, double newValue)
        {
            ValueString = newValue.ToString("F1");
        }
        #endregion

        #region ValueString
        /// <summary>
        /// ValueString Dependency Property
        /// </summary>
        public static readonly DependencyProperty ValueStringProperty =
            DependencyProperty.Register(
                "ValueString",
                typeof(string),
                typeof(SimpleGauge),
                new PropertyMetadata("0"));

        /// <summary>
        /// Gets or sets the ValueString property. This dependency property 
        /// indicates ....
        /// </summary>
        public string ValueString
        {
            get { return (string)GetValue(ValueStringProperty); }
            set { SetValue(ValueStringProperty, value); }
        }
        #endregion

        public SimpleGauge()
        {
            this.InitializeComponent();
        }
    }
}

Now with a few more minutes you can get a nicer needle:

gauges_angle

<UserControl
    x:Class="App98.SimpleGauge"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400"
    Width="200"
    Height="200"
    IsHitTestVisible="False"
    x:Name="Root">
    <Grid
        DataContext="{Binding ElementName=Root}">
        <Ellipse
            Opacity="0.5"
            Fill="WhiteSmoke"
            Stretch="Fill" />
        <Grid
            Margin="1">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBlock
                Text="{Binding ValueString}"
                Foreground="LightGray"
                FontSize="18"
                Grid.Row="1"
                HorizontalAlignment="Center"
                VerticalAlignment="Center" />
            <Polygon
                HorizontalAlignment="Center"
                VerticalAlignment="Stretch"
                Stretch="Uniform"
                Fill="Red"
                Points="0,0 -0.02,1 0.02,1"
                RenderTransformOrigin="0.5,1">
                <Polygon.RenderTransform>
                    <RotateTransform
                        Angle="{Binding Value}" />
                </Polygon.RenderTransform>
            </Polygon>
        </Grid>
    </Grid>
</UserControl>
Advertisements
Tagged , , , ,

4 thoughts on “The five minute gauge control for WinRT/XAML

  1. […] The Five Minute Gauge Control for Winrt/Xaml (Filip Skakun) […]

  2. […] Read original post at Filip Skakun's Blog […]

    • xyzzer says:

      That looks like a dial/knob! Always wanted to create one! Now I’ll just steal yours! Mwahahaha! πŸ™‚
      Can I get use some or all of your code and add the control to my toolkit?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: