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… 🙂
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:
<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>
[…] The Five Minute Gauge Control for Winrt/Xaml (Filip Skakun) […]
[…] Read original post at Filip Skakun's Blog […]
And, here’s the 10 minute gauge 🙂 http://blog.jerrynixon.com/2012/12/walkthrough-building-sweet-dial-in-xaml.html
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?