Weather Underground Widget

Operations Dashboard for ArcGIS with the Weather Underground Widget sample

This Operations Dashboard for ArcGISsample demonstrates how to implement a custom widget that implements IMapConsumer, and shows weather observations for the center of a map widget.

Operations Dashboard for ArcGIS samples are supported only in Visual Studio 2012. A live preview is not available.

To run this sample, you must first sign up free for a Weather Underground developer key and enter it in the source code. Open the solution in Visual Studio 2012, and enter your developer key in the widget source code where indicated. Then set the Start Action and Start Options debug options in the Project Properties as described in the Testing add-ins help topic, and build and run the project.

Download Sample Application
XAML C# VB.NET
<UserControl x:Class="WundergroundWidgetCS.WeatherUndergroundWidget"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:opsDash="clr-namespace:ESRI.ArcGIS.OperationsDashboard;assembly=ESRI.ArcGIS.OperationsDashboard"
             xmlns:c="clr-namespace:WundergroundWidgetCS.ValueConverters"
             mc:Ignorable="d"
             d:DesignHeight="300"
             d:DesignWidth="300">
  <UserControl.Resources>
    
    <Style x:Key="LabelFontStyle" TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
      <Setter Property="Margin" Value="0,5,5,5" />
      <Setter Property="FontFamily" Value="Segoe UI" />
      <Setter Property="FontWeight" Value="Bold" />
      <Setter Property="Foreground" Value="{DynamicResource ThemedSecondaryTextBrush}" />
    </Style>

    <Style x:Key="ValueFontStyle" TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
      <Setter Property="Margin" Value="0,5,5,5" />
      <Setter Property="FontFamily" Value="Segoe UI" />
      <Setter Property="FontWeight" Value="Bold" />
      <Setter Property="Foreground" Value="{DynamicResource ThemedForegroundBrush}" />
    </Style>

    <Style x:Key="TabRadioButtonStyle" TargetType="{x:Type RadioButton}">
      <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
      <Setter Property="Background" Value="{DynamicResource ThemedBackgroundBrush}"/>
      <Setter Property="BorderBrush" Value="{DynamicResource ThemedAccentBrush}"/>
      <Setter Property="HorizontalContentAlignment" Value="Center" />
      <Setter Property="VerticalContentAlignment" Value="Center" />
      <Setter Property="BorderThickness" Value="1"/>
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type RadioButton}">
            <Border x:Name="RBBorder"
						        Background="{TemplateBinding Background}"
						        BorderBrush="{TemplateBinding BorderBrush}"
								CornerRadius="0,0,2,2"
								BorderThickness="1" >
              <ContentPresenter x:Name="ContentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </Border>
            <ControlTemplate.Triggers>
              <Trigger Property="IsChecked" Value="true">
                <Setter Property="BorderThickness" TargetName="RBBorder" Value="1,0,1,1"/>
                <Setter Property="Margin" TargetName="ContentPresenter" Value="0,1,0,0"/>
              </Trigger>
              <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
    
  </UserControl.Resources>

  <Grid x:Name="LayoutRoot">

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CustomStates">
          <VisualState x:Name="Details" >
            <Storyboard>
              <DoubleAnimation Duration="0:0:0.25"
                                       To="1"
                                       Storyboard.TargetProperty="(UIElement.Opacity)"
                                       Storyboard.TargetName="WeatherDetails" />
              <DoubleAnimation Duration="0:0:0.25"
                                       To="0"
                                       Storyboard.TargetProperty="(UIElement.Opacity)"
                                       Storyboard.TargetName="WeatherMap" />
            </Storyboard>
          </VisualState>
          <VisualState x:Name="Map" >
            <Storyboard>
              <DoubleAnimation Duration="0:0:0.25"
                                       To="0"
                                       Storyboard.TargetProperty="(UIElement.Opacity)"
                                       Storyboard.TargetName="WeatherDetails" />
              <DoubleAnimation Duration="0:0:0.25"
                                       To="1"
                                       Storyboard.TargetProperty="(UIElement.Opacity)"
                                       Storyboard.TargetName="WeatherMap" />
            </Storyboard>
          </VisualState>
        </VisualStateGroup>
      </VisualStateManager.VisualStateGroups>

    <Grid.RowDefinitions>
      <RowDefinition Height="auto"/>
      <RowDefinition Height="auto"/>
      <RowDefinition Height="*"/>
      <RowDefinition Height="auto"/>
    </Grid.RowDefinitions>

      <!-- Missing developer key message -->
    <TextBlock Grid.RowSpan="4" Visibility="{Binding NoDeveloperKey, Converter={c:BoolToVisibilityConverter}}"   
               Text="Enter a Weather Underground developer key to run this sample"
               Margin="5" Foreground="{DynamicResource ThemedForegroundBrush}" Background="{DynamicResource ThemedBackgroundBrush}" FontSize="{DynamicResource ThemedMediumTextSize}"
               TextWrapping="Wrap" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" />


    <StackPanel Margin="10" Visibility="{Binding NoDeveloperKey, Converter={c:BoolToVisibilityConverter}, ConverterParameter=invert}" >

      <TextBlock Text="{Binding Path=observation.DisplayLocation.FullLocationName}"  FontWeight="Normal" FontSize="18"
               Style="{StaticResource LargeTextBlockStyle}" Foreground="{DynamicResource ThemedForegroundBrush}"/>
      <TextBlock Text="{Binding Path=observation.ObservationTime}" Foreground="{DynamicResource ThemedSecondaryTextBrush}"/>
        
    </StackPanel>

    <Rectangle Grid.Row="1" Visibility="{Binding NoDeveloperKey, Converter={c:BoolToVisibilityConverter}, ConverterParameter=invert}"
               Style="{StaticResource HorizontalAccentRectangleStyle}" Fill="{DynamicResource ThemedAccentBrush}" Margin="3" />

    <Image x:Name="WeatherMap" Grid.Row="2" Grid.ColumnSpan="2" Visibility="{Binding NoDeveloperKey, Converter={c:BoolToVisibilityConverter}, ConverterParameter=invert}"
           Source="{Binding Path=satelliteImage.VisibleSatelliteImage}" Margin="2" Opacity="0" />

    <Grid x:Name="WeatherDetails" Grid.Row="2" VerticalAlignment="Top" Visibility="{Binding NoDeveloperKey, Converter={c:BoolToVisibilityConverter}, ConverterParameter=invert}">
        
      <Grid.ColumnDefinitions>
          <ColumnDefinition Width="auto"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

      <Grid Margin="20,0"
          VerticalAlignment="Center">
          <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
          </Grid.RowDefinitions>
          <TextBlock Text="{Binding Path=observation.Temperature}" 
                 Grid.Row="1"
                 HorizontalAlignment="Center"
                   Style="{StaticResource MediumTextBlockStyle}"
                   Foreground="{DynamicResource ThemedForegroundBrush}"/>
          <Image Source="{Binding Path=observation.WeatherIconURL}" 
               Stretch="None"
               Margin="2"/>
        </Grid>

      <Grid Grid.Column="1" 
          HorizontalAlignment="Center"
            Margin="0,10">
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
          </Grid.ColumnDefinitions>

          <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
          </Grid.RowDefinitions>

          <TextBlock Text="{Binding Path=observation.Weather}"
                 Grid.ColumnSpan="2"
                 Style="{StaticResource MediumTextBlockStyle}"
                 Foreground="{DynamicResource ThemedForegroundBrush}"
                 FontWeight="Bold"
                 HorizontalAlignment="Left"/>

          <TextBlock Text="Wind"
                 Grid.Row="1"
                   Style="{StaticResource LabelFontStyle}"/>
          <TextBlock Text="{Binding Path=observation.WindInfo}" 
                   Grid.Row="1"
                   Grid.Column="1" 
                   VerticalAlignment="Center"
                   TextWrapping="Wrap" 
                   Style="{StaticResource ValueFontStyle}"/>
          <TextBlock Text="Precip" 
                   Grid.Row="2"
                   Style="{StaticResource LabelFontStyle}"/>
          <TextBlock Text="{Binding Path=observation.PrecipitationToday}" 
                   Grid.Row="2" 
                   Grid.Column="1" 
                   VerticalAlignment="Center" 
                   Style="{StaticResource ValueFontStyle}" />
          <TextBlock Text="Precip (24hrs)" 
                   Grid.Row="3"
                   Style="{StaticResource LabelFontStyle}"/>
          <TextBlock Text="{Binding Path=observation.PrecipitationToday}" 
                   Grid.Row="3" 
                   Grid.Column="1"
                   VerticalAlignment="Center"
                   Style="{StaticResource ValueFontStyle}" />

          <TextBlock Text="Humidity" 
                   Grid.Row="4"
                   Style="{StaticResource LabelFontStyle}"/>
          <TextBlock Text="{Binding Path=observation.RelativeHumidity}" 
                   Grid.Row="4" 
                   Grid.Column="1"
                   VerticalAlignment="Center"
                   Style="{StaticResource ValueFontStyle}" />

          <TextBlock Text="Dew Point" 
                   Grid.Row="5"
                   Style="{StaticResource LabelFontStyle}"/>
          <TextBlock Text="{Binding Path=observation.Dewpoint}" 
                   Grid.Row="5" 
                   Grid.Column="1"
                   VerticalAlignment="Center"
                   Style="{StaticResource ValueFontStyle}" />

          <TextBlock Text="Visibility" 
                   Grid.Row="6"
                   Style="{StaticResource LabelFontStyle}"/>
          <TextBlock Text="{Binding Path=observation.Visibility}" 
                   Grid.Row="6" 
                   Grid.Column="1"
                   VerticalAlignment="Center"
                   Style="{StaticResource ValueFontStyle}" />
        </Grid>

    </Grid>

    <Rectangle Grid.Row="3" VerticalAlignment="Top" Visibility="{Binding NoDeveloperKey, Converter={c:BoolToVisibilityConverter}, ConverterParameter=invert}"
               Style="{StaticResource HorizontalAccentRectangleStyle}" Fill="{DynamicResource ThemedAccentBrush}" StrokeThickness="0" />

    <StackPanel Orientation="Horizontal" Grid.Row="3" Visibility="{Binding NoDeveloperKey, Converter={c:BoolToVisibilityConverter}, ConverterParameter=invert}"
                Margin="10,0,0,10">
        
        <RadioButton x:Name="ListRB" IsChecked="True" Height="40" Width="40" Checked="RadioButton_Checked" Unchecked="RadioButton_Checked"
                   Style="{StaticResource TabRadioButtonStyle}" ToolTip="Details">
          <Path Data="M30.707001,52.895L63.441002,52.895 63.441002,58.181999 30.707001,58.181999z M0,47.075001L16.922001,47.075001 16.922001,64 0,64z M30.707001,29.372L63.441002,29.372 63.441002,34.66 30.707001,34.66z M0,23.555L16.922001,23.555 16.922001,40.478001 0,40.478001z M30.707001,5.8150005L63.441002,5.8150005 63.441002,11.103 30.707001,11.103z M0,0L16.922001,0 16.922001,16.921 0,16.921z"
              Stretch="Uniform" Fill="{DynamicResource ThemedForegroundBrush}" Margin="7" RenderTransformOrigin="0.5,0.5">
            <Path.RenderTransform>
              <TransformGroup>
                <TransformGroup.Children>
                  <RotateTransform Angle="0" />
                  <ScaleTransform ScaleX="1" ScaleY="1" />
                </TransformGroup.Children>
              </TransformGroup>
            </Path.RenderTransform>
          </Path>
        </RadioButton>
        
        <RadioButton x:Name="MapRB" Height="40" Width="40" Margin="3,0,0,0" Style="{StaticResource TabRadioButtonStyle}" ToolTip="Map">
          <Path Data="F1M-1802.07,-3405.59C-1819.37,-3405.59 -1833.4,-3391.56 -1833.4,-3374.26 -1833.4,-3356.95 -1819.37,-3342.92 -1802.07,-3342.92 -1784.76,-3342.92 -1770.73,-3356.95 -1770.73,-3374.26 -1770.73,-3391.56 -1784.76,-3405.59 -1802.07,-3405.59 M-1796.01,-3364.05L-1802.72,-3354.17C-1805.51,-3348.19,-1803.78,-3347.17,-1803.78,-3347.17L-1806.83,-3347.17C-1805.71,-3348.03 -1809.66,-3353.65 -1809.66,-3353.65 -1809.14,-3355.36 -1810.78,-3363.03 -1810.78,-3363.03 -1816.34,-3366.78 -1813.71,-3370.87 -1813.71,-3370.87 -1811.79,-3372.58 -1818.35,-3376.16 -1818.35,-3376.16 -1822.58,-3375.43 -1823.98,-3379.83 -1823.98,-3379.83 -1825.85,-3379.57 -1826.02,-3381.1 -1826.02,-3381.1 -1828.75,-3385.71 -1821.76,-3393.38 -1821.76,-3393.38 -1811.53,-3404.12 -1800.61,-3400.88 -1800.61,-3400.88 -1801.3,-3400.37 -1801.32,-3399.52 -1801.32,-3399.52 -1797.41,-3396.45 -1802.72,-3395.6 -1802.72,-3395.6 -1802.27,-3394.24 -1800.1,-3392.36 -1800.1,-3392.36 -1799.6,-3386.39 -1802.72,-3390.14 -1802.72,-3390.14L-1802.72,-3388.44C-1806.88,-3386.73 -1808.68,-3384.69 -1808.68,-3384.69 -1814.2,-3377.7 -1813.71,-3382.13 -1813.71,-3382.13 -1821.34,-3380.59 -1818.01,-3378.72 -1818.01,-3378.72 -1815.62,-3380.42 -1815.11,-3378.03 -1815.11,-3378.03L-1812.62,-3375.14 -1808.68,-3376.16C-1806.35,-3376.16 -1797.04,-3369.55 -1797.04,-3369.55 -1792.95,-3368.06 -1796.01,-3364.05 -1796.01,-3364.05 M-1795.16,-3396.79L-1797.04,-3400.88 -1788,-3396.79C-1790.47,-3396.96,-1795.16,-3396.79,-1795.16,-3396.79 M-1777.31,-3370.37C-1785.54,-3370.02 -1788,-3374.12 -1788,-3374.12 -1792.09,-3379.57 -1783.86,-3384.86 -1783.86,-3384.86 -1787.38,-3387.58 -1782.88,-3388.95 -1782.88,-3388.95L-1782.88,-3390.66C-1786.8,-3391.17 -1783.56,-3394.4 -1783.56,-3394.4 -1770.26,-3380.94 -1776.46,-3365.25 -1776.46,-3365.25 -1777.54,-3366.44 -1777.31,-3370.37 -1777.31,-3370.37"
              Stretch="Uniform" Fill="{DynamicResource ThemedForegroundBrush}" Margin="6" />
        </RadioButton>
        
      </StackPanel>

  </Grid>

</UserControl>
Sample code usage restrictions
5/16/2014