wpf 向ViewModelLocator传递参数

baubqpgj  于 2023-08-07  发布在  其他
关注(0)|答案(1)|浏览(156)

我在WPF应用程序的App.xaml.cs中使用 Microsoft.Extensions.DependencyInjection NuGet包设置了依赖注入,并在其中注册了MainViewModel

App.xaml.cs

public partial class App : Application
{
    private IServiceProvider _serviceProvider;

    protected void OnStartup(object sender, StartupEventArgs startupEventArgs)
    {
        ConfigureServices();

        var mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
        mainWindow.Show();
    }

    private void ConfigureServices()
    {
        var services = new ServiceCollection();

        services.AddSingleton<MainViewModel>();

        services.AddSingleton<MainWindow>();

        _serviceProvider = services.BuildServiceProvider();
    }
}

字符串
我创建了一个ViewModelLocator类来连接我的MainViewModelMainWindow。我将ViewModelLocator添加到App.xaml中的应用程序资源,并使用此ViewModelLocator应用程序资源,将MainWindow.xamlDataContext设置为MainViewModel

ViewModelLocator.cs

public class ViewModelLocator
{
    private readonly IServiceProvider _serviceProvider;

    public ViewModelLocator(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public MainViewModel MainViewModel => CreateViewModel<MainViewModel>();

    private T CreateViewModel<T>()
    {
        return _serviceProvider.GetRequiredService<T>();
    }
}

App.xaml

<Application x:Class="MyApp.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:MyApp"
         xmlns:locators="clr-namespace:MyApp.ViewModels.Locators"
         Startup="OnStartup">
    <Application.Resources>
        <locators:ViewModelLocator x:Key="ViewModelLocator"/>
    </Application.Resources>
</Application>

MainWindow.xaml

<Window x:Class="MyApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:MyApp"
    xmlns:locators="clr-namespace:MyApp.ViewModels.Locators"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800"
    DataContext="{Binding MainViewModel, Source={StaticResource ViewModelLocator}}">

<Grid>
</Grid>
</Window>


有了这个解决方案,我得到的错误,我想通了为什么. ViewModelLocator需要有一个无参数构造函数。但是,我仍然需要能够在CreateViewModel方法中从ServiceProvider获取视图模型。我是怎么做到的?

fiei3ece

fiei3ece1#

我设法解决了这个问题。我根据Singleton模式创建了MyDependencyInjection类,并将App.xaml.cs中的逻辑移到其中。类看起来像这样。

MyDependencyInjection.cs

public class MyDependencyInjection
{
    private IServiceProvider? _serviceProvider;

    private static MyDependencyInjection? _instance;
    public static MyDependencyInjection Instance
    {
        get
        {
            if(_instance == null)
                _instance = new MyDependencyInjection();
            return _instance;
        }
    }

    private MyDependencyInjection()
    {
        SetupContainer();
    }

    public T GetRequiredService<T>()
    {
        return _serviceProvider.GetRequiredService<T>();
    }

    private void SetupContainer()
    {
        var container = new ServiceCollection();

        container.AddSingleton<MainViewModel>();

        container.AddSingleton<MainWindow>();

        _serviceProvider = container.BuildServiceProvider();
    }
}

字符串
并更新了ViewModelLocator,现在如下所示。

public class ViewModelLocator
{
    public MainViewModel MainViewModel => CreateViewModel<MainViewModel>();

    private static T CreateViewModel<T>()
    {
        return MyDependencyInjection.Instance.GetRequiredService<T>();
    }
}


我解决了这个问题,但我觉得这不是最好的解决方案。所以我仍然很好奇什么是最好的做法。谢谢你的建议。

相关问题