I have a WPF application. In the main window on the left is a listbox with several entries, and on the right is a ContentControl into which, when selecting one of the entries, the UserControl along with the view model should be loaded.
Next, when selecting one of the entries in the listbox, a UserControl instance with a view model should be created, the selected element from the listbox or one of its fields should be passed to the view model constructor.
I do not know how to do this correctly without creating a new instance of the UserControl and view model manually, without violating the principles of DI, if you create an instance manually, then the application is not cleared from memory when closed.
MainView.Xaml:
<ListBox ItemsSource="{Binding ContainerList}" SelectedItem="{Binding SelectedContainer}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction Command="{Binding ShowContent}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
<ContentControl Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Content="{Binding TheContent}"></ContentControl>
Code behind:
public partial class MainView : Window
{
public MainView(IMainViewModel viewModel)
{
this.DataContext = viewModel;
InitializeComponent();
}
}
public class MainViewModel : ViewModelBase, IMainViewModel
{
private readonly IRepositories _repositories;
private readonly IAbstractFactory<ChangeExecutorView> _factory;
public ObservableCollection<Container> ContainerList { get; set; }
private Container _SelectedContainer { get; set; }
public Container SelectedContainer { get { return _SelectedContainer; } set { _SelectedContainer = value; OnPropertyChanged(nameof(SelectedContainer)); }
}
private object _TheContent { get; set; }
public object TheContent
{
get { return _TheContent; }
set {_TheContent = value; OnPropertyChanged(nameof(TheContent)); }
}
// public MainViewModel(IContainerRepository repContainer, IAbstractFactory<ChangeExecutorView> factory)
public MainViewModel(IRepositories repositories, IAbstractFactory<ChangeExecutorView> factory)
{
_repositories = repositories;
_factory = factory;
ContainerList = new ObservableCollection<Container>(_repositories.ContainerRepository.GetAll());
}
// Here is action for create new UserControl
public ICommand ShowContent
{
get {
return new RelayCommand(delegate (object param)
{
// var content = new ContainerContentView(
// new ContainerContentViewModel(_repositories, SelectedUserID));
});
}
}
}
public interface IMainViewModel
{
ObservableCollection<Container> ContainerList { get; set; }
}
app.xaml:
public static IHost AppHost { get; set; }
public App()
{
AppHost = Host.CreateDefaultBuilder()
.ConfigureHostConfiguration((hostConfiguration => {
hostConfiguration.AddJsonFile("appsettings.json",false,true)
.AddEncryptedProvider()
.AddJsonFile($"appsettings.json", false, true);
}))
.ConfigureServices((hostConext, services) =>
{
services.AddSingleton<MainView>();
services.AddTransient<IMainViewModel, MainViewModel>();
services.AddTransient<IRepositories,Repositories>();
services.AddFormFactory<ChangeExecutorView>();
services.AddScoped<ContainerContentViewModel>();
})
.Build();
}
public static T GetService<T>() where T : class
{
var service = AppHost.Services.GetService(typeof(T)) as T;
return service;
}
protected override async void OnStartup(StartupEventArgs e)
{
await AppHost.StartAsync();//.ConfigureAwait(true);
var startupForm = AppHost.Services.GetRequiredService<MainView>();
startupForm.Show();
base.OnStartup(e);
}
protected override async void OnExit(ExitEventArgs e)
{
await AppHost.StopAsync();
base.OnExit(e);
}
}