Home > OS >  WPF pass parameter to page with factory delegate
WPF pass parameter to page with factory delegate

Time:06-22

I dont how to pass parameter to new page, I have factory delegate that help me with dependecy injection but I also want to pass parameter throught Navigate service.

App.xml

private void ConfigureServices(ServiceCollection serviceCollection)
    {
        serviceCollection.AddTransient<Home>();
        serviceCollection.AddSingleton<Func<Home>>(ServiceProvider => ServiceProvider.GetService<Home>);

        serviceCollection.AddTransient<PrinterDetails>();
        serviceCollection.AddSingleton<Func<PrinterDetails>>(ServiceProvider => ServiceProvider.GetService<PrinterDetails>);

        serviceCollection.AddTransient<ProvinceList>();
        serviceCollection.AddSingleton<Func<ProvinceList>>(ServiceProvider => ServiceProvider.GetService<ProvinceList>);

        serviceCollection.AddSingleton(Configuration);
        serviceCollection.AddTransient<ISqlDataAccess, SqlDataAccess>();
        serviceCollection.AddTransient<IProvinceListViewModel, ProvinceListViewModel>();
        
        serviceCollection.AddTransient(typeof(MainWindow));
    }

I navigate from page PrinterDetails to page ProvinceList using NavigationService(when i click btnProvince_Click())

public partial class PrinterDetails : Page, INotifyPropertyChanged
{
    private Func<ProvinceList> ProvinceListFactory { get; }

    
    public PrinterDetails(Func<ProvinceList> provinceListFactory)
    {
        InitializeComponent();
        DataContext = this;

        PrinterService printerService = new PrinterService();
        cmbPrinterList.ItemsSource = printerService.PrinterList();
        ProvinceListFactory = provinceListFactory;
   
    }


    private void btnProvince_Click(object sender, RoutedEventArgs e)
    {
  
        ProvinceList nextPage = this.ProvinceListFactory.Invoke();
        NavigationService.Navigate(nextPage);
    }
}

ProvinceList page that i want to pass parameter

public partial class ProvinceList : Page
{
    private readonly IProvinceListViewModel _provinceListViewModel;

    public ProvinceList(IProvinceListViewModel provinceListViewModel)
    {
        InitializeComponent();
        _provinceListViewModel = provinceListViewModel;
        GetProvinceList();
    }

    private void GetProvinceList()
    {
        //How to get parameter from previous page
    }
}

CodePudding user response:

You can implement a public property on ProvinceList. Then PrinterDetails can set this property after it has created the instance using the factory:

private void btnProvince_Click(object sender, RoutedEventArgs e)
{
  double parameter = 4.5;
  ProvinceList nextPage = this.ProvinceListFactory.Invoke();
  nextPage.Value = parameter;
  NavigationService.Navigate(nextPage);
}

Alternatively, you can add this parameter to the constructor of ProvinceList and then configure the IoC container to inject the parameter. If the parameter is a dynamic result you must configure your factory to accept this parameter. Register the factory delegate that accepts a parameter e.g. Func<IProvinceListViewModel, double, ProvinceList>, which is used to construct the type:

// This example assumes that the constructor of ProvinceList 
// requests two parameters of type IProvinceListViewModel and double
serviceCollection.AddSingleton<Func<double, ProvinceList>>(serviceProvider => doubleParameter => 
{
  IProvinceListViewModel viewModel = serviceProvider.GetService<IProvinceListViewModel>();
  return new ProvinceList(viewModel, doubleParameter);
});

serviceCollection.AddTransient<IProvinceListViewModel, ProvinceListViewModel>();

And use the factory as follows:

public PrinterDetails(Func<double, ProvinceList> provinceListFactory)
{
  InitializeComponent();
  ProvinceListFactory = provinceListFactory;
}

private void btnProvince_Click(object sender, RoutedEventArgs e)
{
  double constructorParameter = 4.5;
  ProvinceList nextPage = this.ProvinceListFactory.Invoke(constructorParameter);
  NavigationService.Navigate(nextPage);
}

Answer to follow up question:

// This example assumes that the constructor of ProvinceList 
// requests two parameters of type IProvinceListViewModel and double
serviceCollection.AddSingleton<Func<double, ProvinceList>>(serviceProvider => doubleParameter => 
{
  IProvinceListViewModel viewModel = serviceProvider.GetService<IProvinceListViewModel>();
  Func<POPList> popListFactory = serviceProvider.GetService<Func<POPList>>();
  return new ProvinceList(viewModel, doubleParameter, popListFactory);
});

serviceCollection.AddTransient<IProvinceListViewModel, ProvinceListViewModel>();
serviceCollection.AddTransient<POPList>();
serviceCollection.AddSingleton<Func<POPList>>(serviceProvider => serviceProvider.GetService<POPList>);
private void btnProvince_Click(object sender, RoutedEventArgs e)
{
  double constructorParameter = 4.5;
  ProvinceList nextPage = this.ProvinceListFactory.Invoke(constructorParameter);
  NavigationService.Navigate(nextPage);
}
  • Related