Binding 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», ничего не произошло.

Что я делаю неправильно?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
39
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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;   
}

Кредиты идут в Rand Random.

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

Rand Random 13.03.2019 14:13

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

4est 13.03.2019 14:39

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

Rand Random 13.03.2019 18:26

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

4est 14.03.2019 09:00

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

Rand Random 14.03.2019 13:48

Чтобы уточнить: первый ответ верен и для запрошенного варианта использования. В запрошенном варианте использования модель представления создается в представлении, и это автоматически вызывает конструктор по умолчанию. Поскольку всегда полезно вызывать конструктор по умолчанию из всех специальных конструкторов, я также добавил эту опцию. Но специальный конструктор в этой реализации не используется, поэтому без разницы! Если вам нужно IExcelService в вашей модели представления, вы должны получить его откуда-то еще (или сначала создать экземпляр модели представления, а представление из нее).

Nicolas 14.03.2019 14:17

это нормально, я также добавил экземпляр класса в первый ctor, а «CopyCommand» переместил во второй ctor, без этого, и он отлично работает, большое спасибо за помощь, ребята!

4est 15.03.2019 08:44

Другие вопросы по теме