Home > Blockchain >  DelegateCommand<T> Object reference not set to an instance of an object
DelegateCommand<T> Object reference not set to an instance of an object

Time:03-19

I am adding a new Button with functionality to a large existing WPF client application. The Button Command should fire a method on the view model through a DelegateCommand<T>. The problem is that the whole application crashes on start, apparently because of this DelegateCommand<T>. My code is as follows.

BaseFormViewModel (inherited by PensionTakerViewModel)

public DelegateCommand<DocumentType> AddFileCommand { get; private set; }

public BaseFormViewModel(...)
{
    this.AddFileCommand = new DelegateCommand<DocumentType>(this.ExecuteAddFileCommand);
}

protected virtual void ExecuteAddFileCommand(DocumentType documentType)
{
  // Do something...
}

PensionTakerView

<ctrl:ErrorDecorator Grid.Row="1" Grid.Column="0">
    <ComboBox AutomationProperties.AutomationId="cmbDocumentType" 
              ItemsSource="{Binding ViewModel.DocumentTypes, ElementName=Root}" 
              DisplayMemberPath="Name" 
              SelectedValuePath="Value"
              SelectedValue="{Binding DocumentType}"/>
</ctrl:ErrorDecorator>
                
<Button Grid.Row="1" Grid.Column="2" Content="Tilføj fil" 
        Command="{Binding ViewModel.AddFileCommand, ElementName=Root}"
        CommandParameter="{Binding DocumentType}"/>

Now the application is crashing on start and the interesting part of the stack trace is as follows (I have anonymized customer names and terms). Sorry for the small sized image. enter image description here

I am quite new to both WPF and MVVM, so it's a bit of a learning curve for me. But from what I understand, it is complaining about the second parameter of the DelegateCommand<T> which is the CanExecute method. But DelegateCommand<T> also has a constructor which only takes one parameter - the Execute method. So why is it complaining over this?

I have tried also passing in a CanExecute method which just returns true. But the application is still crashing with the same error.

This same use of DelegateCommand<T> is existing several places in the application with the same syntax and signature with no problems. So this really shouldn't be an issue.

I have also tried using an ICommand and having the ExecuteAddFileCommand without parameters. This works for me, but is obviously not a solution as I need to pass a DocumentType.

Can someone please help me get further towards a solution?

CodePudding user response:

I suspect that the command parameter is something else than a DocumentType object.

If you change the type of the command to DelegateCommand<object> you should avoid getting the exception.

Then you could put a breakpoint in your ExecuteAddFileCommand method to determine the actual type of the parameter and whether it has been set at all. If not, check your DocumentType source property that you bind the CommandParameter to:

CommandParameter="{Binding DocumentType}"

It's type must match the type argument of the DelegateCommand<T>.

CodePudding user response:

So I looked further into this today, going with @mm8's theory that my CommandParameter was not of type DocumentType. So I followed the DocumentType all the way through and found that some places it was nullable, and other places it was not. And once I changed my CommandParameter to type DocumentType?, the application stopped crashing. My incoming parameter in ExecuteAddFileCommand() was still null though. And that was ofcourse because I had to include the parameter in the DelegateCommand<T>. So the working code looks like this.

BaseFormViewModel (inherited by PensionTakerViewModel)

public DelegateCommand<DocumentType?> AddFileCommand { get; private set; }

public BaseFormViewModel(...)
{
    this.AddFileCommand = new DelegateCommand<DocumentType?>(param => this.ExecuteAddFileCommand(param));
}

protected virtual void ExecuteAddFileCommand(DocumentType? documentType)
{
  // Do something...
}
  • Related