Привязка RelayCommand не хочет выполняться

#c# #wpf #xaml #command #relaycommand

#c# #wpf #xaml #команда #relaycommand

Вопрос:

У меня есть Page.xaml

 <Page>
  <Page.DataContext>
        <vm:ExcelViewModel />
  </Page.DataContext>

  <Grid>
     <Button Command="{Binding Path=CopyCommand}" Margin="5"/>
  </Grid>
</Page>
  

Вот мой ExcelViewModel.cs

 public ExcelViewModel()
{
  SourcePath = @"\test\2019";
}

private readonly IExcelService fileService;
public ICommand CopyCommand{ get; private set; }

public ExcelViewModel(IExcelService fileService)
{
 this.fileService = fileService;   
 CopyCommand= new RelayCommand(CopyExcel);
}
  

Но когда я попытался запустить «CopyExcel», ничего не произошло.

Что я делаю не так?

Ответ №1:

Вы создаете экземпляр ExcelViewModel класса в XAML, используя конструктор по умолчанию. Ваш CopyCommand инициализируется только во втором конструкторе с параметром.

Измените это на это, и это должно сработать:

 public ExcelViewModel()
{
    SourcePath = @"\test\2019";
    CopyCommand= new RelayCommand(CopyExcel);
}

private readonly IExcelService fileService;
public ICommand CopyCommand{ get; private set; }

public ExcelViewModel(IExcelService fileService)
{
    this.fileService = fileService;   
}
  

Обновить:

Всегда полезно вызывать конструктор по умолчанию из любых специальных конструкторов, как предложил Rand Random.

Это не решит вашу проблему (поскольку ваше представление XAML вызывает конструктор по умолчанию)! Но для справки это будет выглядеть так:

 public ExcelViewModel()
{
    SourcePath = @"\test\2019";
    CopyCommand= new RelayCommand(CopyExcel);
}

private readonly IExcelService fileService;
public ICommand CopyCommand{ get; private set; }

public ExcelViewModel(IExcelService fileService) : this()
{
    this.fileService = fileService;   
}
  

Кредиты переходят к ранду Random.

Комментарии:

1. Вероятно, вы хотите вызвать пустой ctor при использовании того, у которого есть параметры. Так что эта строка, public ExcelViewModel(IExcelService fileService) возможно, должна быть public ExcelViewModel(IExcelService fileService) : this() — не выполняется автоматически, как вы можете видеть здесь: dotnetfiddle.net/XIKqdZ

2. @Rand — должен ли я добавить «это» в мой второй конструктор? не могли бы вы, пожалуйста, записать это в качестве ответа

3. @4est — ответ обновлен корректно, с исходным ответом вы столкнулись бы с той же проблемой, когда вызывали constructor с параметром IExcelService fileService , поскольку теперь вы бы инициализировали CopyCommand не в указанном конструкторе, а только в пустом — поэтому вместо исправления для обоих конструкторов вы только переместили проблему с одного на другой — вызывая empty constructor вы инициализируете CopyCommand независимо от того, что constructor вы используете

4. @Rand как я могу тогда сделать это правильно? теперь проблема в первом или втором ctor

5. @4est — как я уже сказал, ответ получил обновление, которое делает это правильно