title: Custom Indicator Control
body: <p>Control (C# Code):</p>
  
  <pre><code>public partial class RedGreenStatusIndicator : UserControl, INotifyPropertyChanged
  {
      public RedGreenStatusIndicator()
      {
          this.InitializeComponent();
  
          DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty
              (ArchiverDetails.ArDetailsProperty,
              typeof(ArchiverDetails));
  
          dpd.AddValueChanged(this, delegate { this.ObjectValueChanged(); });
          Status = false;
      }
  
      void RedGreenStatusIndicator_Loaded(object sender, RoutedEventArgs e)
      {
  
      }
  
      public bool Status
      {
          get { return (bool)GetValue(StatusProperty); }
          set 
          {
              bool old_value = Status;
              SetValue(StatusProperty, value);
  
              if ((old_value == true) &amp;&amp; (Status == false))
              {
                  hide_green();
                  show_red();
              }
  
              if((old_value == false) &amp;&amp; (Status == true))
              {
                  hide_red();
                  show_green();
              }
          }
      }
  
      private void show_green()
      {
          if (GreenInterior.Opacity == 0)
              run_storyboard("show_green_indicator");
      }
  
      private void hide_green()
      {
          if (GreenInterior.Opacity != 0)
              run_storyboard("hide_green_indicator");
      }
  
      private void show_red()
      {
          if (RedInterior.Opacity == 0)
              run_storyboard("show_red_indicator");
      }
  
      private void hide_red()
      {
          if (RedInterior.Opacity != 0)
              run_storyboard("hide_red_indicator");
      }
  
      private void run_storyboard(string resource_name)
      {
          Storyboard sb = (Storyboard)FindResource(resource_name);
          sb.Begin();
      }
  
      public static readonly DependencyProperty StatusProperty =
          DependencyProperty.Register("Status",
          typeof(bool),
          typeof(RedGreenStatusIndicator),
          new PropertyMetadata(null));
  
      #region INotifyPropertyChanged Members
  
      public event PropertyChangedEventHandler PropertyChanged;
  
      private void ObjectValueChanged()
      {
          OnPropertyChanged("Status");
      }
  
      public void OnPropertyChanged(string propertyName)
      {
          if (PropertyChanged != null)
          {
              PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
          }
      }
  
      #endregion
  }
  </code></pre>
  
  <p>XAML:</p>
  
  <pre><code>&lt;UserControl 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"
               x:Class="Manager.RedGreenStatusIndicator"
               x:Name="UserControl"
               d:DesignWidth="640" d:DesignHeight="480"&gt;
      &lt;UserControl.Resources&gt;
          &lt;Storyboard x:Key="show_green_indicator"&gt;
              &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="GreenInterior" Storyboard.TargetProperty="(UIElement.Opacity)"&gt;
                  &lt;SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/&gt;
                  &lt;SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/&gt;
              &lt;/DoubleAnimationUsingKeyFrames&gt;
          &lt;/Storyboard&gt;
          &lt;Storyboard x:Key="hide_green_indicator"&gt;
              &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="GreenInterior" Storyboard.TargetProperty="(UIElement.Opacity)"&gt;
                  &lt;SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/&gt;
                  &lt;SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0"/&gt;
              &lt;/DoubleAnimationUsingKeyFrames&gt;
          &lt;/Storyboard&gt;
          &lt;Storyboard x:Key="show_red_indicator"&gt;
              &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="RedInterior" Storyboard.TargetProperty="(UIElement.Opacity)"&gt;
                  &lt;SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/&gt;
                  &lt;SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/&gt;
              &lt;/DoubleAnimationUsingKeyFrames&gt;
          &lt;/Storyboard&gt;
          &lt;Storyboard x:Key="hide_red_indicator"&gt;
              &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="RedInterior" Storyboard.TargetProperty="(UIElement.Opacity)"&gt;
                  &lt;SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/&gt;
                  &lt;SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0"/&gt;
              &lt;/DoubleAnimationUsingKeyFrames&gt;
          &lt;/Storyboard&gt;
      &lt;/UserControl.Resources&gt;
      &lt;Border BorderBrush="{DynamicResource SPDC_GRAY}" Background="{DynamicResource SPDC_BLACK}" CornerRadius="5,5,5,5" BorderThickness="1,1,1,1"&gt;
          &lt;Grid Margin="2,2,2,2"&gt;
              &lt;Grid.RowDefinitions&gt;
                  &lt;RowDefinition Height="0.5*"/&gt;
                  &lt;RowDefinition Height="0.5*"/&gt;
              &lt;/Grid.RowDefinitions&gt;
              &lt;Border HorizontalAlignment="Stretch" x:Name="RedInterior" VerticalAlignment="Stretch" Width="Auto" Height="Auto" Grid.RowSpan="2" Background="#FFF21818" Opacity="0"/&gt;
              &lt;Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Height="Auto" Grid.RowSpan="2" x:Name="GreenInterior" Background="#FF1DD286" Opacity="0"/&gt;
              &lt;Border Margin="0,0,0,0" x:Name="Reflection" CornerRadius="5,5,0,0"&gt;
                  &lt;Border.Background&gt;
                      &lt;LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"&gt;
                          &lt;GradientStop Color="#99FFFFFF" Offset="0"/&gt;
                          &lt;GradientStop Color="#33FFFFFF" Offset="1"/&gt;
                      &lt;/LinearGradientBrush&gt;
                  &lt;/Border.Background&gt;
              &lt;/Border&gt;
          &lt;/Grid&gt;
      &lt;/Border&gt;
  &lt;/UserControl&gt;
  </code></pre>
  
  <p>Ok, So here's my control. Basically I intended it to have a public dependency property of type bool, which I could databind-to (hopefully). I've decided to see if it works and I've placed it in my project along with a checkbox, I then used databinding (working in Blend) to bind Status to Checkbox's IsChecked property. I was expecting to have the checkbox toggle the control's color. </p>
  
  <p>The binding looks like this:</p>
  
  <pre><code>&lt;RedGreenStatusIndicator HorizontalAlignment="Left" Margin="100,146,0,0" VerticalAlignment="Top" Width="64" Height="64" Status="{Binding Path=IsChecked, ElementName=checkBox, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="m_indicator"/&gt;
          &lt;CheckBox Margin="212,168,315,0" VerticalAlignment="Top" Height="24" Content="Click Me!" Style="{DynamicResource GlassCheckBox}" Foreground="{DynamicResource SPDC_WHITE}" x:Name="checkBox"/&gt;
  </code></pre>
  
  <p>Also, In the Window's .Loaded I'm doing :</p>
  
  <pre><code>m_indicator.DataContext = this;
  </code></pre>
  
  <p>Here are my questions:</p>
  
  <p>What on earth have I done wrong?
  Will I be able to use this in a ListViewItem template ? The listview is going to be databound to an observable_collection of objects which contain a bool property (which I'm hoping to bind to.</p>
  
  <p>What do I need to do to make it work?</p>