title: Bind Button.CommandParameter to MVVM object to use the same ICommand to different Buttons
body: <p>I have quite a hard time to figure out the solution to a rather trivial problem of mine.</p>
  <p>I have three buttons that execute the same command (same function call). The only thing that changes is that the function call affects different objects per button. So instead of creating the button command 3 times I just created Command parameters that I bind to different MVVM objects. My code below will clear things up.</p>
  <p>My problem is that I don't know how to bind a command parameter to an MVVM object. Towards this direction I get back the following error</p>
  <pre class="lang-cs prettyprint-override"><code>Object of type 'System.Windows.Data.Binding cannot be converted to 'System.Boolean' //or System.String
  </code></pre>
  <p>XAML code to bind the elements together <em>(I have added also the <code>MultiBinding.Converter</code> method as proposed in the submitted answer by Peter)</em></p>
  <p><strong>XAML file</strong></p>
  <pre class="lang-xml prettyprint-override"><code>&lt;Window x:Class=&quot;TestEnvironment.MainWIndowTestStackOverflow&quot;
          x:Name=&quot;MainWindowTestStackOverflow&quot;
          xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
          xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
          xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
          xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
          xmlns:local=&quot;clr-namespace:TestEnvironment&quot;
          mc:Ignorable=&quot;d&quot;
          Height=&quot;720&quot;
          Width=&quot;1145&quot;
          ResizeMode=&quot;NoResize&quot;
          WindowStartupLocation=&quot;CenterScreen&quot;
          BorderBrush=&quot;Black&quot;
          BorderThickness=&quot;1.5,1.5,1.5,1.5&quot;
          WindowStyle=&quot;None&quot;&gt;
      &lt;Window.Resources&gt;
          &lt;BooleanToVisibilityConverter x:Key=&quot;BooleanToVisibilityConverter&quot; /&gt;
      &lt;/Window.Resources&gt;
      &lt;Grid x:Name=&quot;GridMain&quot;
           Width=&quot;1145&quot;
           Background=&quot;White&quot;
           HorizontalAlignment=&quot;Center&quot;
           ShowGridLines=&quot;False&quot; 
           Grid.Row=&quot;1&quot;&gt;
          &lt;!--Grid Columns--&gt;
          &lt;Grid.ColumnDefinitions&gt;
              &lt;ColumnDefinition Width=&quot;0&quot;/&gt;
              &lt;ColumnDefinition Width=&quot;195&quot;/&gt;
              &lt;ColumnDefinition Width=&quot;295&quot;/&gt;
              &lt;ColumnDefinition Width=&quot;650&quot;/&gt;
              &lt;ColumnDefinition Width=&quot;0&quot;/&gt;
          &lt;/Grid.ColumnDefinitions&gt;
          &lt;!--Grid Rows--&gt;
          &lt;Grid.RowDefinitions&gt;
              &lt;RowDefinition Height=&quot;0&quot;/&gt;
              &lt;RowDefinition Height=&quot;45&quot;/&gt;
              &lt;RowDefinition Height=&quot;45&quot;/&gt;
              &lt;RowDefinition Height=&quot;45&quot;/&gt;
              &lt;RowDefinition Height=&quot;45&quot;/&gt;
              &lt;RowDefinition Height=&quot;52&quot;/&gt;
              &lt;RowDefinition Height=&quot;400&quot;/&gt;
          &lt;/Grid.RowDefinitions&gt;
          &lt;TextBox
              Name=&quot;FileNameTextBox&quot;
              Text=&quot;{Binding Path=FilesFilePath}&quot;
              HorizontalAlignment=&quot;Left&quot;
              VerticalAlignment=&quot;Center&quot;
              Margin=&quot;5,0,0,0&quot;
              IsReadOnly=&quot;True&quot;
              FontStyle=&quot;Italic&quot;
              FontFamily=&quot;Arial&quot;
              FontSize=&quot;9&quot;
              BorderThickness=&quot;0&quot;
              Grid.Column=&quot;2&quot;
              Grid.Row=&quot;1&quot;/&gt;
          &lt;!--Apply ICommand to browse file 1st time--&gt;
          &lt;Button 
              x:Name=&quot;BrowseButton1&quot;
              Content=&quot;Browse&quot;
              Command=&quot;{Binding Path=BrowseButtonCommand}&quot;
              IsEnabled=&quot;{Binding Path=EnableFilesBrowseButton, Converter={StaticResource BooleanToVisibilityConverter}}&quot;
              HorizontalAlignment=&quot;Left&quot;
              VerticalAlignment=&quot;Center&quot;
              Width=&quot;80&quot; 
              Height=&quot;25&quot;
              Margin=&quot;40,0,0,0&quot;
              Padding=&quot;0&quot;
              FontWeight=&quot;Light&quot;
              FontSize=&quot;10&quot;
              Grid.Column=&quot;3&quot;
              Grid.Row=&quot;1&quot;
              Cursor=&quot;Hand&quot;&gt;
              &lt;Button.CommandParameter&gt;
                  &lt;MultiBinding&gt;
                      &lt;MultiBinding.Converter&gt;
                          &lt;local:BrowseButtonConverter/&gt;
                      &lt;/MultiBinding.Converter&gt;
                      &lt;Binding Path=&quot;FilesFilePath&quot;/&gt;
                      &lt;Binding Path=&quot;EnableFilesBrowseButton&quot;/&gt;
                      &lt;Binding Path=&quot;EnableFilesLoadButton&quot;/&gt;
                      &lt;Binding Path=&quot;EnableFilesViewButton&quot;/&gt;
                      &lt;Binding Path=&quot;FilesPanelVisibility&quot;/&gt;
                  &lt;/MultiBinding&gt;
              &lt;/Button.CommandParameter&gt;
          &lt;/Button&gt;
          &lt;Button 
              x:Name=&quot;LoadButton1&quot;
              Content=&quot;Load&quot;
              IsEnabled=&quot;{Binding Path=EnableFilesLoadButton, Converter={StaticResource BooleanToVisibilityConverter}}&quot;
              Focusable=&quot;False&quot;
              Width=&quot;80&quot;
              Height=&quot;25&quot;
              Margin=&quot;135,0,0,0&quot;
              FontSize=&quot;10&quot;
              FontWeight=&quot;Light&quot;
              HorizontalAlignment=&quot;Left&quot;
              VerticalAlignment=&quot;Center&quot;
              Grid.Column=&quot;3&quot;
              Grid.Row=&quot;1&quot;
              Cursor=&quot;Hand&quot;&gt;
          &lt;/Button&gt;
          &lt;StackPanel
              x:Name=&quot;StackPanelFiles&quot;
              VerticalAlignment=&quot;Center&quot;
              HorizontalAlignment=&quot;Left&quot;
              Grid.Row=&quot;1&quot;
              Grid.Column=&quot;3&quot;
              Orientation=&quot;Vertical&quot;
              Width=&quot;400&quot;
              Height=&quot;36&quot;
              Margin=&quot;235,0,0,0&quot;
              Visibility=&quot;{Binding XPath=FilesPanelVisibility, Converter={StaticResource BooleanToVisibilityConverter}}&quot;&gt;
          &lt;/StackPanel&gt;
          &lt;Button
              x:Name=&quot;PreviewButton1&quot;
              IsEnabled=&quot;{Binding XPath=EnableFilesViewButton, Converter={StaticResource BooleanToVisibilityConverter}}&quot;
              Focusable=&quot;False&quot;
              Content=&quot;View&quot;
              Width=&quot;80&quot;
              Height=&quot;25&quot;
              Margin=&quot;545,0,0,0&quot;
              FontSize=&quot;10&quot;
              FontWeight=&quot;Light&quot;
              HorizontalAlignment=&quot;Left&quot;
              VerticalAlignment=&quot;Center&quot;
              Grid.Column=&quot;3&quot;
              Grid.Row=&quot;1&quot;
              Cursor=&quot;Hand&quot;&gt;
          &lt;/Button&gt;
          &lt;!--Apply ICommand to browse file 2nd time--&gt;
          &lt;TextBox
              Name=&quot;FileNameTextBoxLayout&quot;
              Text=&quot;{Binding Path=LayoutFilePath}&quot;
              HorizontalAlignment=&quot;Left&quot;
              VerticalAlignment=&quot;Center&quot;
              Height=&quot;25&quot;
              Margin=&quot;5,6,0,0&quot;
              IsReadOnly=&quot;True&quot;
              FontStyle=&quot;Italic&quot;
              FontFamily=&quot;Arial&quot;
              FontSize=&quot;9&quot;
              BorderThickness=&quot;0&quot;
              Grid.Column=&quot;2&quot; 
              Grid.Row=&quot;3&quot;/&gt;
          &lt;Button 
              x:Name=&quot;BrowseButton2&quot;
              Content=&quot;Browse&quot;
              Command=&quot;{Binding Path=BrowseButtonCommand}&quot;
              IsEnabled=&quot;{Binding Path=EnableLayoutBrowseButton, Converter={StaticResource BooleanToVisibilityConverter}}&quot;
              HorizontalAlignment=&quot;Left&quot;
              VerticalAlignment=&quot;Center&quot;
              Width=&quot;80&quot; 
              Height=&quot;25&quot;
              Margin=&quot;40,0,0,0&quot;
              Padding=&quot;0&quot;
              FontWeight=&quot;Light&quot;
              FontSize=&quot;10&quot;
              Grid.Column=&quot;3&quot;
              Grid.Row=&quot;2&quot;
              Cursor=&quot;Hand&quot;&gt;
              &lt;Button.CommandParameter&gt;
                  &lt;MultiBinding&gt;
                      &lt;MultiBinding.Converter&gt;
                          &lt;local:BrowseButtonConverter/&gt;
                      &lt;/MultiBinding.Converter&gt;
                      &lt;Binding Path=&quot;LayoutFilePath&quot;/&gt;
                      &lt;Binding Path=&quot;EnableLayoutBrowseButton&quot;/&gt;
                      &lt;Binding Path=&quot;EnableLayoutLoadButton&quot;/&gt;
                      &lt;Binding Path=&quot;EnableLayoutViewButton&quot;/&gt;
                      &lt;Binding Path=&quot;LayoutPanelVisibility&quot;/&gt;
                  &lt;/MultiBinding&gt;
              &lt;/Button.CommandParameter&gt;
          &lt;/Button&gt;
          &lt;Button 
              x:Name=&quot;LoadButton2&quot;
              Content=&quot;Load&quot;
              IsEnabled=&quot;{Binding Path=EnableLayoutLoadButton, Converter={StaticResource BooleanToVisibilityConverter}}&quot;
              Focusable=&quot;False&quot;
              Width=&quot;80&quot;
              Height=&quot;25&quot;
              Margin=&quot;135,0,0,0&quot;
              FontSize=&quot;10&quot;
              FontWeight=&quot;Light&quot;
              HorizontalAlignment=&quot;Left&quot;
              VerticalAlignment=&quot;Center&quot;
              Grid.Column=&quot;3&quot;
              Grid.Row=&quot;2&quot;
              Cursor=&quot;Hand&quot;&gt;
          &lt;/Button&gt;
          &lt;!--...The rest of the controls as created above but with different names--&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  <p>The binding elements like <code>FilesFilePath</code>, <code>EnableFilesBrowseButton</code>, etc are MVVM objects that bind to other XAML objects and get affected by the ICommand.</p>
  <p>Now I present to you the c# code with the MVVM objects and ICommand function:
  <strong>.cs file</strong></p>
  <pre class="lang-cs prettyprint-override"><code>namespace TestEnvironment
  {
      //Command parameters
      public class BrowseButtonCommandParameters
      {
          public string FilePathSelected { get; set; } //parameter 1
          public bool EnableBrowseButton { get; set; } //parameter 2
          public bool EnableLoadButton { get; set; } //parameter 3
          public bool EnableViewButton { get; set; } //parameter 4
          public bool VisibilityPanel { get; set; } //parameter 5
      }
      //Browse - MultiValueConverter
      class BrowseButtonConverter : IMultiValueConverter
      {
          public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
              // Error handling omitted for brevity
              // Casting omitted because question's code has insufficient context
              return new BrowseButtonCommandParameters
              {
                  FilePathSelected = (string)values[0],
                  EnableBrowseButton = (bool)values[1],
                  EnableLoadButton = (bool)values[2],
                  EnableViewButton = (bool)values[3],
                  VisibilityPanel = (bool)values[4],
              };
          }
  
          public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
          {
              throw new NotSupportedException(&quot;to-source binding mode not supported&quot;);
          }
      }
      
      public class MainWindowViewModel : INotifyPropertyChanged
      {
          //----------------------------------------------------------------------------------------------------
          //MVVM objects binded to xaml objects and connected to ICommand parameters
  
          //Used by BrowseButton1
          //1.
          private bool _enableFilesLoadButton;
          public bool EnableFilesLoadButton
          {
              get
              {
                  return _enableFilesLoadButton;
              }
              set
              {
                  _enableFilesLoadButton = value;
                  OnPropertyChanged(&quot;EnableFilesLoadButton&quot;);
              }
          }
  
          //2.
          private bool _enableFilesBrowseButton;
          public bool EnableFilesBrowseButton
          {
              get
              {
                  return _enableFilesBrowseButton;
              }
              set
              {
                  _enableFilesBrowseButton = value;
                  OnPropertyChanged(&quot;EnableFilesBrowseButton&quot;);
              }
          }
  
          //3.
          private bool _enableFilesViewButton;
          public bool EnableFilesViewButton
          {
              get
              {
                  return _enableFilesViewButton;
              }
              set
              {
                  _enableFilesViewButton = value;
                  OnPropertyChanged(&quot;EnableFilesViewButton&quot;);
              }
          }
  
          //4.
          private string _FilesFilePath;
          public string FilesFilePath
          {
              get
              {
                  return _FilesFilePath;
              }
              set
              {
                  _FilesFilePath = value;
                  OnPropertyChanged(&quot;FilesFilePath&quot;);
              }
          }
  
          //5.
          private bool _changeFilesPanelVisibility;
          public bool FilesPanelVisibility
          {
              get
              {
                  return _changeFilesPanelVisibility;
              }
              set
              {
                  _changeFilesPanelVisibility= value;
                  OnPropertyChanged(&quot;FilesPanelVisibility&quot;);
              }
          }
  
          //Used by BrowseButton2
          //1.
          private bool _enableLayoutLoadButton;
          public bool EnableLayoutLoadButton
          {
              get
              {
                  return _enableLayoutLoadButton;
              }
              set
              {
                  _enableLayoutLoadButton = value;
                  OnPropertyChanged(&quot;EnableLayoutLoadButton&quot;);
              }
          }
  
          //2.
          private bool _enableLayoutBrowseButton;
          public bool EnableLayoutBrowseButton
          {
              get
              {
                  return _enableLayoutBrowseButton;
              }
              set
              {
                  _enableLayoutBrowseButton = value;
                  OnPropertyChanged(&quot;EnableLayoutBrowseButton&quot;);
              }
          }
  
          //3.
          private bool _enableLayoutViewButton;
          public bool EnableLayoutViewButton
          {
              get
              {
                  return _enableLayoutViewButton;
              }
              set
              {
                  _enableLayoutViewButton = value;
                  OnPropertyChanged(&quot;EnableLayoutViewButton&quot;);
              }
          }
  
          //4.
          private string _LayoutFilePath;
          public string LayoutFilePath
          {
              get
              {
                  return _LayoutFilePath;
              }
              set
              {
                  _LayoutFilePath = value;
                  OnPropertyChanged(&quot;LayoutFilePath&quot;);
              }
          }
  
          //5.
          private bool _changeLayoutPanelVisibility;
          public bool LayoutPanelVisibility
          {
              get
              {
                  return _changeLayoutPanelVisibility;
              }
              set
              {
                  _changeLayoutPanelVisibility= value;
                  OnPropertyChanged(&quot;LayoutPanelVisibility&quot;);
              }
          }
  
  
          //----------------------------------------------------------------------------------------------------
          //ICommand: BrowseButtonCommand
          public ICommand BrowseButtonCommand
          {
              get { return new DelegateCommand&lt;object&gt;(FuncBrowseCommand); }
          }
          public void FuncBrowseCommand(object parameters)
          {
              var param = (BrowseButtonCommandParameters)parameters;
  
              //Load button gets instantly disabled when every time the user clicks the Browse Button 
              param.EnableLoadButton = false;
  
              Nullable&lt;bool&gt; browse_result = BrowseFile(param.FilePathSelected);
  
              //Browse file
              if (browse_result == true)
              {
                  param.EnableBrowseButton = true;
                  param.EnableLoadButton = true;
                  param.EnableViewButton = false;
                  param.VisibilityPanel = false;
              }
              else
              {
                  return;
              }
          }
  
          public event PropertyChangedEventHandler PropertyChanged;
          public void OnPropertyChanged(string property)
          {
              this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
          }
      }
  }
  </code></pre>
  <p><em>Note: Inside the ICommand function <code>BrowseButtonCommand</code> I call a method named <code>BrowseFile</code>. Don't pay attention to that because the function I present works perfectly.</em></p>
  <p>My goal and concern is how can I bind the command parameters with the MVVM objects and adopt their values. How to pass a command.parameter value to an MVVM object. For example, I want the Command Parameter <code>FilePathSelected</code> to get the value of the MVVM object <code>FilesFilePath</code></p>
  <p>And then when I use the same command for a different browse button <code>BrowseButton2</code> I should be able to provide the values of the MVVM objects of my second Browse Button like</p>
  <pre class="lang-cs prettyprint-override"><code>&lt;Button 
      x:Name=&quot;BrowseButton2&quot;
      Content=&quot;Browse&quot;
      Command=&quot;{Binding Path=BrowseButtonCommand}&quot;&gt;
      &lt;Button.CommandParameter&gt; //Parameters that share value with MVVM objects of the second Browse Button
          &lt;local:BrowseButtonCommandParameters FilePathSelected=&quot;{Binding Path=LayoutFilePath}&quot; //those return the error I mentioned earlier.
                                               EnableBrowseButton=&quot;{Binding Path=EnableLayoutBrowseButton}&quot;
                                               EnableLoadButton=&quot;{Binding Path=EnableLayoutLoadButton}&quot;
                                               EnableViewButton=&quot;{Binding Path=EnableLayoutViewButton}&quot;
                                               VisibilityPanel=&quot;{Binding Path=LayoutPanelVisibility}&quot;/&gt;
      &lt;/Button.CommandParameter&gt;
  &lt;/Button&gt;
  </code></pre>
  <p>Do you know how can I achieve this? I think I am on the correct path, although it's clear that I miss something. I have created my MVVM objects, my ICommand function, although I want to bind them together so the one to take the value of the other. As I mentioned I need to do this for three Browse Buttons (<code>BrowseButton1</code>, <code>BrowseButton2</code>, <code>BrowseButton3</code>). Thus, I don't want to create three ICommands but rather only one.</p>
  <p>I am more than willing to share with you more info about my question in case there is something misunderstood.</p>