У меня есть 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», ничего не произошло.
Что я делаю неправильно?





Вы создаете экземпляр класса 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.
@Rand - должен ли я добавить «это» во второй конструктор? не могли бы вы написать это как ответ
@4est - ответ был обновлен правильно, с исходным ответом вы столкнулись бы с той же проблемой, когда вызывали constructor с параметром IExcelService fileService, поскольку теперь вы не инициализируете CopyCommand в указанном конструкторе, а только в пустом - поэтому вместо этого исправить это для обоих конструкторов, вы только переместили проблему с одного на другой - вызывая empty constructor вы инициализируете CopyCommand независимо от того, что constructor вы используете
@Rand, как я могу сделать это правильно? теперь проблема в первом или втором ctor
@4est - как я уже сказал, ответ получил обновление - что делает это правильно
Чтобы уточнить: первый ответ верен и для запрошенного варианта использования. В запрошенном варианте использования модель представления создается в представлении, и это автоматически вызывает конструктор по умолчанию. Поскольку всегда полезно вызывать конструктор по умолчанию из всех специальных конструкторов, я также добавил эту опцию. Но специальный конструктор в этой реализации не используется, поэтому без разницы! Если вам нужно IExcelService в вашей модели представления, вы должны получить его откуда-то еще (или сначала создать экземпляр модели представления, а представление из нее).
это нормально, я также добавил экземпляр класса в первый ctor, а «CopyCommand» переместил во второй ctor, без этого, и он отлично работает, большое спасибо за помощь, ребята!
Вероятно, вы хотите вызвать пустой ctor при использовании с параметрами. Так что эта строка
public ExcelViewModel(IExcelService fileService), возможно, должна бытьpublic ExcelViewModel(IExcelService fileService) : this()- не происходит автоматически, как вы можете видеть здесь: dotnetfiddle.net/XIKqdZ