WPF требует объектов, которые создаются в XAML для определения конструктора без параметров.
Существует много способов достижения sh Внедрения зависимостей в WPF с использованием MVVM. При поиске в inte rnet наиболее распространенным решением кажется ViewModelLocator, еще одна реализация локатора служб, которая широко рассматривается как анти-шаблон (например, печально известный контейнер stati c Singleton Io C).
Простым решением является использование композиции. Вы создаете модель основного вида, которая состоит из других моделей видов, каждая из которых предназначена для определенного вида.
MainViewModel.cs
class MainViewModel
{
public MainViewModel(IFirstControlViewModel firstControlViewModel ,
ISecondControlViewModel secondControlViewModel)
{
this.FirstControlViewModel = firstControlViewModel;
this.SecondControlViewModel = secondControlViewModel;
}
public IFirstControlViewModel FirstControlViewModel { get; }
public ISecondControlViewModel SecondViewModel { get; }
}
FirstViewModel .cs
class FirstViewModel : IFirstViewModel
{
}
SecondViewModel.cs
class SecondViewModel : ISecondViewModel
{
public SecondVieModel(IThirdViewModel thirdViewModel) => this.ThirdViewModel = thirdViewModel;
public IThirdViewModel ThirdViewModel { get; }
}
MainWindow.xaml
<Window>
<StackPanel>
<FirstUserControl DataContext="{Binding FirstViewModel}" />
<SecondUserControl DataCOntext="{Binding SecondViewModel}" />
</StackPanel>
</Window>
SecondUserControlxaml
<UserControl>
<Grid>
<ThirdUserControl DataContext="{Binding ThirdViewModel}" />
</Grid>
</UserControl>
App.xaml.cs
private void Run(StartupEventArgs e)
{
IMainViewModel viewModel = container.GetExportedValue<IMainViewModel>();
var mainWindow = new MainWindow { DataContext = viewModel };
mainWindow.Show();
}
Или используйте только композицию верхнего уровня:
MainViewModel.cs
class MainViewModel
{
public MainViewModel(IFirstControlViewModel firstControlViewModel ,
ISecondControlViewModel secondControlViewModel,
IThirdViewModel thirdViewModel)
{
this.FirstControlViewModel = firstControlViewModel;
this.SecondControlViewModel = secondControlViewModel;
this.ThirdViewModel = thirdViewModel;
}
public IFirstControlViewModel FirstControlViewModel { get; }
public ISecondControlViewModel SecondViewModel { get; }
public IThirdViewModel ThirdViewModel { get; }
}
App.xaml.cs
private void Run(StartupEventArgs e)
{
IMainViewModel viewModel = container.GetExportedValue<IMainViewModel>();
// For simplicity, you can add the view model to the globally accessible App.xaml ResourceDictionary
this.Resources.Add("MainViewModel", viewModel);
var mainWindow = new MainWindow { DataContext = viewModel };
mainWindow.Show();
}
SecondUserControlxaml
<UserControl>
<Grid>
<ThirdUserControl DataContext="{Binding Source="{StaticResource MainViewModel}", Path=ThirdViewModel}" />
</Grid>
</UserControl>
Композиция - очень простое решение для использования Dependency Injection с представлениями. Если производительность, например, классы с большим деревом зависимостей, является проблемой, многие структуры DI, такие как MEF, поддерживают Lazy<T>
export.