Caliburn Micro : passing Object between ViewModel

99封情书 提交于 2020-01-14 02:00:34

问题


I'm developing a simple Crud Application (a windows 8.1 store application) using Caliburn Micro 2.0.0-alpha2

I'm in trouble with navigation between viewmodels, passing object.

I read many times the solution proposed by

Anders Gustafsson (How to pass parameter to navigated view model with WinRT Caliburn.Micro?)

and i tried to adapt it to my scope. But the object is alwais null.

I need to pass a single object selected from a listView to my crudPage. The crudPage is composed by an userControl that shown the FormView. So i want to initialize this Form, with the values of the passed object.

I think that the problem is that the "Parameter" is initialized only after the ViewModel is created, but i don't know how to fix that problem.

There is my code, according with the idea of Anders Gustafsson

TransporterListViewModel (a list of Transporters from Database)

public class TransporterListViewModel : ViewModelBase
{
    public string Title { get; set; }
    public TransporterListViewModel(INavigationService navigationService)
        : base(navigationService)
    {
        LoadData();
    }

    public async void LoadData() {

        _transporters = await TransporterService.GetAll();
    }

    private BindableCollection<Transporter> _transporters;

    public BindableCollection<Transporter> Transporters
    {
        get
        {
            return this._transporters;
        }
        set
        {
            this._transporters = value;
            NotifyOfPropertyChange(() => this.Transporters);
        }
    }

    private Transporter _selectedItem;
    public Transporter SelectedItem
    {
        get 
        {

            return _selectedItem;
        }

        set
        {
            _selectedItem = value;
            NotifyOfPropertyChange(() => this.SelectedItem);

            navigationService.Navigated += NavigationServiceOnNavigated;
            navigationService.NavigateToViewModel<TransporterCrudPageViewModel>(_selectedItem;);
            navigationService.Navigated -= NavigationServiceOnNavigated;
        }
    }

    private static void NavigationServiceOnNavigated(object sender, NavigationEventArgs args)
    {
        FrameworkElement view;
        TransporterCrudPageViewModel transporterCrudPageViewModel;
        if ((view = args.Content as FrameworkElement) == null ||
            (transporterCrudPageViewModel = view.DataContext as TransporterCrudPageViewModel) == null) return;

        transporterCrudPageViewModel.InitializeTransporterForm(args.Parameter as Transporter);
    } 

TransporterCrudViewModel (the page that cointains the UserControl to initialize)

public class TransporterCrudPageViewModel : ViewModelBase
{
    public string Title { get; set; }

    public Transporter Parameter { get; set; }
    public TransporterFormViewModel TransporterFormVM { get; set; }

    public async void InitializeTransporterForm(Transporter enumerable)
    {
        TransporterFormVM = new TransporterFormViewModel(navigationService, enumerable);
        await SetUpForm(enumerable);
    }

    public async Task SetUpForm(Transporter t){
        TransporterFormVM.trName = t.trName;
        TransporterFormVM.trUrl = t.trUrl;

    }
    public TransporterCrudPageViewModel(INavigationService navigationService)
        : base(navigationService)
    {
        Title = "TransporterCrud Page";
        //this.navigationService = navigationService;

        this.InitializeTransporterForm(Parameter);

    }

TransporterFormViewModel (the userContol to initialize)

    public class TransporterFormViewModel :ViewModelBase
{


    public string Title { get; set; }

    public Transporter Transporter { get; set; }

    public TransporterFormViewModel(INavigationService navigationService,Transporter trans)
        : base(navigationService)
    {
        Transporter = trans;
    }



    private string _trName;
    public string trName 
    {
        get
        {
            return _trName;
        }
        set
        {
            _trName = value;
            NotifyOfPropertyChange(() => trName);
        }
    }


    public string trCode { get; set; }
    public string trUrl { get; set; }

    public int trId { get; set; }

回答1:


In the constructor TransporterCrudViewModel class you have:

this.InitializeTransporterForm(Parameter);

where Parameter is a property of type Transporter not initialized and you will call the method InitializeTransporterForm with a null parameter. Then you'll call SetUpForm method with a null value of the parameter Transporter t. I think you should initialize in some way this property.

Then, supposing you're continuing in your TransporterListViewModel class with this:

transporterCrudPageViewModel.InitializeTransporterForm(args.Parameter as Transporter);

in the method InitializeTransporterForm, you don't set the passed parameter as value of the property Parameter with something like this:

public async void InitializeTransporterForm(Transporter enumerable)
{
     TransporterFormVM = new TransporterFormViewModel(navigationService, enumerable);
     this.Parameter = enumerable; //setting the Parameter property..
     await SetUpForm(enumerable);
}

Beside these notes, you should put a breakpoint with your IDE in the line

transporterCrudPageViewModel.InitializeTransporterForm(args.Parameter as Transporter);

Make sure that the property Parameter of the NavigationEventArgs object is not null.



来源:https://stackoverflow.com/questions/22659918/caliburn-micro-passing-object-between-viewmodel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!