title: Binding of control visibility to ViewModel property doesn't work
body: <p>I'm in the process of converting a fairly large WPF app from three-layer into MVVM, and in the process learning MVVM. So far, I haven't delved into too much detail around Bindings (etc), so bear with me.</p>
  
  <p>I'm trying to bind the System.Windows.Visibility of multiple controls to a public property ("State") of the ViewModel. When the parent TabItem loads, the State property is read and handled as desired. When subsequent changes to the property are made, however, they appear to be ignored. I've (re-re-re-)checked Bindings, debugged the Converters, etc, and this is driving me crazy.</p>
  
  <p>ViewModel:</p>
  
  <pre><code>public class MarketingListViewModel: IDisposable, INotifyPropertyChanged
  {
      private UiState state;
  
      public event PropertyChangedEventHandler PropertyChanged;
      public UiState State 
      {
          get { return state; }
          set
          {
              if (state != value)
              {
                  state = value;
                  NotifyPropertyChanged("State");
              }
          }
      }
  
      public MarketingListViewModel() 
      {
          State = UiState.View;
      }
  
      private void NotifyPropertyChanged(String info) 
      {
          if (PropertyChanged != null)
          {
              PropertyChanged(this, new PropertyChangedEventArgs(info));
          }
      }
  
  }
  </code></pre>
  
  <p>View:</p>
  
  <pre><code>&lt;UserControl 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:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
           mc:Ignorable="d" x:Class="WpfCrm.tabListManager" xmlns:DPH="clr-namespace:DPH" &gt;
  
  &lt;UserControl.Resources&gt;
      &lt;DPH:MarketingListViewModel x:Key="listVM" /&gt;
      &lt;!-- Note that the above line is giving me an "Object reference not set to an instance of an object" error --&gt;
  &lt;/UserControl.Resources&gt;
  
  &lt;Grid x:Name="gridMain" DataContext="{StaticResource listVM}" &gt;
  
      &lt;Border Grid.Row="0" Grid.Column="1" Margin="10"
              Style="{StaticResource WidgetStyle}" &gt;
          &lt;Grid x:Name="gridListManagement" &gt;
              &lt;Label x:Name="labelManageLists" Content="Manage Lists" MouseDown="labelManageLists_MouseDown"
                  Style="{StaticResource WidgetTitleStyle}"
                  Grid.Row="0" Grid.Column="0" /&gt;
  
              &lt;StackPanel Grid.Row="0" Grid.Column="2" Orientation="Horizontal"  HorizontalAlignment="Right" &gt;
                  &lt;Label x:Name="llNewList" Content="new" MouseDown="llNewList_MouseDown"
                      Style="{StaticResource LinkLabelStyle}"
                      HorizontalAlignment="Right" /&gt;
                  &lt;Label x:Name="llCloseManageLists" Content="close" MouseDown="llCloseManageLists_MouseDown" 
                      Style="{StaticResource LinkLabelStyle}"
                      HorizontalAlignment="Right" /&gt;
              &lt;/StackPanel&gt;
  
              &lt;Label x:Name="labelListName" Content="Name" Grid.Row="1" Grid.Column="0" /&gt;
              &lt;Grid Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" &gt;
                  &lt;ComboBox x:Name="cbLists" SelectedIndex="-1" SelectionChanged="cbLists_SelectionChanged" IsReadOnly="True"
                            ItemsSource="{Binding Path=AllMarketingLists}" 
                            DisplayMemberPath="Name" 
                            SelectedValuePath="Id"
                            Visibility="{Binding Path=State, Converter={StaticResource ViewStateToVisibilityConverter} }"/&gt;
                  &lt;TextBox x:Name="tbListName" 
                           Text="{Binding Path=OList.Name}"
                           Visibility="{Binding Path=State, Converter={StaticResource EditStateToVisibilityConverter} }"/&gt;
              &lt;/Grid&gt;
  
              &lt;Label x:Name="labelListDescription" Content="Description" Grid.Row="2" Grid.Column="0" /&gt;
              &lt;Grid Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" &gt;
                  &lt;TextBlock x:Name="textblockListDescription" TextWrapping="Wrap" 
                             Text="{Binding Path=OList.Notes}"
                             Visibility="{Binding Path=State, Converter={StaticResource ViewStateToVisibilityConverter} }"
                             Grid.ColumnSpan="2" /&gt;
                  &lt;TextBox x:Name="tbListDescription" TextWrapping="Wrap"
                           Text="{Binding Path=OList.Notes}"
                           Visibility="{Binding Path=State, Converter={StaticResource EditStateToVisibilityConverter} }"
                           Grid.ColumnSpan="2" /&gt;
              &lt;/Grid&gt;
  
              &lt;StackPanel Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3" HorizontalAlignment="Right" Orientation="Horizontal" &gt;
                  &lt;Button x:Name="buttonEditList" Content="Edit" Click="buttonEditList_Click"
                          Visibility="{Binding Path=State, Converter={StaticResource ViewStateToVisibilityConverter} }"
                          Width="60" Margin="3" /&gt;
                  &lt;Button x:Name="buttonSaveList" Content="Save" Click="buttonSaveList_Click"
                          Visibility="{Binding Path=State, Converter={StaticResource EditStateToVisibilityConverter} }"
                          Width="60" Margin="3" /&gt;
                  &lt;Button x:Name="buttonCancel" Content="Cancel" Click="buttonCancel_Click" 
                          Visibility="{Binding Path=State, Converter={StaticResource EditStateToVisibilityConverter} }"
                          Width="60" Margin="3" /&gt;
              &lt;/StackPanel&gt;
  
          &lt;/Grid&gt;
      &lt;/Border&gt;
  
  &lt;/Grid&gt;
  </code></pre>
  
  <p></p>
  
  <p>And the code-behind has a few methods like:</p>
  
  <pre><code>    private void buttonEditList_Click(object sender, RoutedEventArgs e) 
      {
          listVM.State = UiState.Edit;
      }
  </code></pre>
  
  <p>Does anyone have ideas on why the controls aren't updating their visibility after the State change? </p>
  
  <p>Kind thanks,</p>
  
  <p>DPH</p>
  
  <p>EDIT -- Converters:</p>
  
  <pre><code>[ValueConversion(typeof(WpfCrm.UiState), typeof(System.Windows.Visibility))]
  public class EditStateToVisibilityConverter: IValueConverter
  {
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      {
          UiState state = (UiState)value;
          if (state == UiState.View) return Visibility.Collapsed;
          else return Visibility.Visible;
      }
  
      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      {
          return null;
      }
  }
  
  [ValueConversion(typeof(WpfCrm.UiState), typeof(System.Windows.Visibility))]
  public class ViewStateToVisibilityConverter : IValueConverter
  {
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      {
          UiState state = (UiState)value;
          if (state == UiState.View) return Visibility.Visible;
          else return Visibility.Collapsed;
      }
  
      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      {
          return null;
      }
  }
  </code></pre>