title: How can I pass any DataGridTextColumn to a single Command which will toggle the Visibility of the DataGridTextColumn?
body: <p>I have a DataGrid and would like to toggle Visibility of individual DataGridTextColumns with Commands sent from a ContextMenu. I need some way to associate a particular DataGridTextColumn, or its Visibility parameter with a ContextMenu MenuItem Command. I can set an individual Visibility variables in my ViewModel and toggle them with individual Commands, one per DataGridTextColumn, that works just fine, but I have many many DataGridTextColumns and that seems like a very repetitive, messy, and probably incorrect way to solve the problem.</p>
  
  <p>Example .xaml:</p>
  
  <pre><code> &lt;FrameworkElement x:Name="dummyElement" Visibility="Collapsed"/&gt;
  
              &lt;DataGrid ItemsSource="{Binding Shots}" SelectedItem="{Binding SelectedShot, Mode=TwoWay}" AutoGenerateColumns="False" HorizontalScrollBarVisibility="Auto" IsReadOnly="True" AreRowDetailsFrozen="True" HeadersVisibility="All" &gt;
  
                  &lt;DataGrid.Columns&gt;
                      &lt;DataGridTextColumn Visibility="{Binding DataContext.ShotNumberColumnVisibility, Source={x:Reference dummyElement}}" Binding="{Binding Path=ShotNumber}" Header="Shot #" /&gt;
                  &lt;/DataGrid.Columns&gt;
  
                  &lt;DataGrid.ContextMenu&gt;
                      &lt;ContextMenu&gt;
                          &lt;MenuItem Header="Toggle Visibility"&gt;
                              &lt;MenuItem Header="Shot Count" Command="{Binding ToggleVisibilityCommand}" /&gt;
                          &lt;/MenuItem&gt;
                      &lt;/ContextMenu&gt;
                  &lt;/DataGrid.ContextMenu&gt;
  
              &lt;/DataGrid &gt;
  
  </code></pre>
  
  <p>Currently, my View .xaml looks like the example above, but with way more Columns and a corresponding ContextMenu MenuItem for each. In my ViewModel, I can control the visibility by changing ShotNumberVisibility. </p>
  
  <pre><code>
  public MyViewModel()
  {
      ToggleVisibilityCommand = new RelayCommand(ToggleVisibility);
  }
  
  
  public Visibility ShotNumberColumnVisibility { get; set; } = Visibility.Visible;
  
  
  public void ToggleVisibility(object obj)
  {
      ShotNumberColumnVisibility = ShotNumberColumnVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
      RaisePropertyChanged("ShotNumberColumnVisibility");
  }
  </code></pre>
  
  <p>I do NOT want to have to set this up for each individual DataGridTextColumn. What is the correct way to pass any DataGridTextColumn to my ViewModel so that it's visibility can be toggled with a generic method? </p>
  
  <p>From what I have seen, it sounds like I need to be able to use CommandParameter to send any DataGridTextColumn to my ToggleVisibility function. This is the part I can't figure out. I'm thinking something like the following in my .xaml but I haven't had it work yet.</p>
  
  <pre><code>CommandParameter="{Binding ElementName=InclinationColumn, Path=Visibility}"
  
  </code></pre>
  
  <p>In case it's still not clear, here's some pseudocode for the command I would like to have and how I would like to use it.</p>
  
  <pre><code>&lt;DataGridTextColumn Name="demoColumn" Visibility="{Binding demoColumnVisibility}" /&gt;
  &lt;MenuItem Header="Toggle Demo Column Visibility" CommandParameter="{Binding demoColumn.Visibility}" Command="{Binding ToggleVisibility}" /&gt;
  
  </code></pre>
  
  <pre><code>public void ToggleVisibility(object obj)
  {
      obj.Visibility = !obj.Visibility
      //OR MAYBE
      //Pass in the name "demoColumn" and use that select which bool to flip. In this case demoColumnVisibility
  
  
  }
  </code></pre>
  
  <p>Here's what my RelayCommand:ICommand class looks like...</p>
  
  <pre><code> public class RelayCommand : ICommand
      {
          readonly Action&lt;object&gt; _execute;
          readonly Predicate&lt;object&gt; _canExecute;
  
          public RelayCommand(Action&lt;object&gt; execute, Predicate&lt;object&gt; canExecute)
          {
              if(execute == null)
              {
                  throw new NullReferenceException("execute");
              }
              _execute = execute;
              _canExecute = canExecute;
          }
  
          public RelayCommand(Action&lt;object&gt; execute) : this(execute, null)
          {
          }
  
  
          public event EventHandler CanExecuteChanged
          { 
              add { CommandManager.RequerySuggested += value; }
              remove { CommandManager.RequerySuggested -= value; }
          }
  
          public bool CanExecute(object parameter)
          {
              return _canExecute == null ? true : _canExecute(parameter);
          }
  
          public void Execute(object parameter)
          {
              _execute.Invoke(parameter);
          }
      }
  </code></pre>
  
  <p>Hopefully that's enough, this problem has been killing me for hours and I feel like I'm missing something basic. Any help is much appreciated.</p>