创建新视图时如何在视图模型中初始化 属性?

How can I initialize a property in a viewmodel when creating a new view?

我有一个应用程序可以打开一个允许您搜索数据的视图。但是,为了进行搜索,用户必须 select 他想在哪个类别下搜索。目前,我正在尝试弄清楚如何将 selected 类别从主视图模型(作为 int)传递到新搜索视图的视图模型。目前我正在尝试在主视图中使用类似这样的东西:

假设我有两个视图 View1View2 每个视图模型。 View2ViewlModel 看起来像这样:

public class View2ViewlModel : ViewModelBase
{
    private IDataService _dataService;     

    public int DivisionIdnt {get; set;}

    public View2ViewModel(IDataService dataService)
    { 
        _dataService = dataService;
    }
}

View1 中,我们在收到消息时创建并打开 View2

public View2()
{
    InitializeComponent();
    Messenger.Default.Register<NotificationMessage<int>>(this, (m) => NotificationMesageReceived(m, m.Content));
}

private void NotificationMesageReceived(NotificationMessage<int> msg, int divisionIdnt)
{
    if (msg.Notification == "SearchCred")
    {
        var findCredentialView = new View2();

        findCredentialView.ShowDialog();
    }
}

消息获取在 View1ViewModel 中作为用户单击搜索按钮时发生的操作的一部分传递。 问题是我想将 View2ViewModel 中的 DivisionIdnt 属性 初始化为新 View2 的值 divisionIdnt 形成消息.我怎样才能做到这一点? 我想在代码中实例化一个 View2ViewModel,将 DivisionIdnt 设置为消息参数,然后设置新 [=15= 的 DataContext ]到新创建的viewmodel,像这样:

private void NotificationMesageReceived(NotificationMessage<int> msg, int divisionIdnt)
{
    if (msg.Notification == "SearchCred")
    {
        var findCredentialView = new View2();

        var vm = new View2ViewModel();
        vm.DivisionIdnt = divisionIdnt;

        findCredentialView.DataContext = vm;

        findCredentialView.ShowDialog();
    }
}

但是,这不起作用,因为在 View2ViewModel 中,构造函数有一个 IDataService 由 DI 在运行时注入。

您是否尝试先初始化视图模型,然后将其传递给视图?

public View2(View2ViewModel vm)
{
    InitializeComponent();
    Messenger.Default.Register<NotificationMessage<int>>(this, (m) => NotificationMesageReceived(m, m.Content));
}
private void NotificationMesageReceived(NotificationMessage<int> msg, int divisionIdnt)
{
    if (msg.Notification == "SearchCred")
    {
        var vm = new View2ViewModel();
        vm.DivisionIdnt = divisionIdnt;
        var findCredentialView = new View2(vm); 
        findCredentialView.ShowDialog();
    }
}

在实例化 View2ViewModel 之前,您不能只解析容器中的 IDataService 实例吗?

如何执行此操作取决于您使用的 DI 容器,但对于 AutoFac,它将是:

    var findCredentialView = new View2();
    var dataService = Container.Resolve<IDataService>();
    var vm = new View2ViewModel(dataService);
    vm.DivisionIdnt = divisionIdnt;

    findCredentialView.DataContext = vm;

    findCredentialView.ShowDialog();

或者,您可以从容器中解析 View2ViewModel:

    var findCredentialView = new View2();
    var vm = Container.Resolve<View2ViewModel>();
    vm.DivisionIdnt = divisionIdnt;

    findCredentialView.DataContext = vm;

    findCredentialView.ShowDialog();

哪个会为您处理 ctor 注入。

显然,这两种方法都要求您在运行时引用您的容器,但大多数 applications/containers 都会为您提供这一点。如果他们不这样做,只需根据您的喜好在 bootstrap 时间通过 service/singleton/static 公开您的容器。

您可能还会发现此答案有帮助:How to handle dependency injection in a WPF/MVVM application