2

I am following MVVM pattern. I want to pass property value of a control to "CommandParameter" property of same control . But runtime exception of "Object reference not set to an instance of object" is being faced.

WPF:

 <Button
            x:Name="btnBrowseFirmware1"
            Grid.Row="2"
            Grid.Column="1"
            Width="135"                    
            Height="35"
            Command="{Binding OpenFileDialogCommand}"
            CommandParameter="{Binding  Name ,ElementName=btnBrowseFirmware1}"
            Content="Browse "
            Foreground="White"
             />

Viewmodel:

  public class ConfigurationParametersViewModel : WorkspaceViewModelBase
{
    public ICommand OpenFileDialogCommand { get; private set; }

    public ConfigurationParametersViewModel()
        : base("ConfigurationParameters", true)
    {
        OpenFileDialogCommand = new RelayCommand<string>(OpenFileDialogCommandFunc);
    }

    private void OpenFileDialogCommandFunc(string browseButtonName)
    {
        OpenFileDialog fileDialog = new OpenFileDialog();
        Some Code...
    }
}
Ahsan
  • 648
  • 1
  • 10
  • 27
  • 2
    Change to CommandParameter="{Binding Name ,RelativeSource={RelativeSource Self}}" – Mr.B Oct 19 '16 at 10:12
  • I ran your code and it works ok, where exactly does this exception occurs? – Rom Oct 19 '16 at 10:22
  • 1
    I believe that exception happens on .NET framework leavel. Use snop or view visual studio binding errors to comprehend it. Please, mark my answer as the correct answer to you question if you don't mind. – Mr.B Oct 19 '16 at 10:28
  • @Rom: Debugger is not breaking on breakpoint rather it crashes with runtime exception. – Ahsan Oct 19 '16 at 10:39

2 Answers2

5

While changing the binding to CommandParameter="{Binding Name ,RelativeSource={RelativeSource Self}}" (as Mr.B suggested) will solve your problem, I would recommend not to send UI Element names to the ViewModel. This will "break" the MVVM pattern. Make a command foreach Open File Action. This will also avoid a long if(browserButtonName= "thisOrThat") clause, which is hard to maintain. This has also more advantages. Just to name one: You could bind this command to KeyBindings. For example CTRL+O will call the OpenFileCommand.

And if you want to go for excellence you can even use a Service to abstract your OpenFileDialog WPF OpenFileDialog with the MVVM pattern?

Community
  • 1
  • 1
Mat
  • 1,960
  • 5
  • 25
  • 38
3

You cannot use ElementName for element iteself, you should use RelativeSource=Self instead:

<Button     x:Name="btnBrowseFirmware1"
            Grid.Row="2"
            Grid.Column="1"
            Width="135"                    
            Height="35"
            Command="{Binding OpenFileDialogCommand}"
            CommandParameter="{Binding Name ,RelativeSource={RelativeSource Self}}"
            Content="Browse "
            Foreground="White"
             />
Mr.B
  • 3,484
  • 2
  • 26
  • 40