【问题标题】:Caliburn Micro : passing Object between ViewModelCaliburn Micro:在 ViewModel 之间传递对象
【发布时间】:2014-05-04 18:59:50
【问题描述】:

我正在使用 Caliburn Micro 2.0.0-alpha2 开发一个简单的 Crud 应用程序(一个 Windows 8.1 商店应用程序)

我在视图模型之间导航、传递对象时遇到了麻烦。

我多次阅读

提出的解决方案

安德斯·古斯塔夫森 (How to pass parameter to navigated view model with WinRT Caliburn.Micro?)

我尝试将其调整到我的范围。 但该对象始终为空。

我需要将从 listView 中选择的单个对象传递给我的 crudPage。 crudPage 由显示 FormView 的 userControl 组成。 所以我想用传递的对象的值初始化这个表单。

我认为问题在于“参数”仅在创建 ViewModel 后才初始化,但我不知道如何解决该问题。

这是我的代码,根据 Anders Gustafsson 的想法

TransporterListViewModel(来自数据库的传输器列表)

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(包含要初始化的 UserControl 的页面)

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(要初始化的 userContol)

    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; }

【问题讨论】:

    标签: c# mvvm winrt-xaml caliburn.micro


    【解决方案1】:

    在构造函数TransporterCrudViewModel 类中你有:

    this.InitializeTransporterForm(Parameter);
    

    其中ParameterTransporter 类型的属性未初始化,您将使用null 参数调用方法InitializeTransporterForm。然后您将使用参数Transporter t 的空值调用SetUpForm 方法。我认为你应该以某种方式初始化这个属性。

    然后,假设您继续在 TransporterListViewModel 上课:

    transporterCrudPageViewModel.InitializeTransporterForm(args.Parameter as Transporter);
    

    在方法InitializeTransporterForm 中,您不要将传递的参数设置为属性Parameter 的值,如下所示:

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

    除了这些注释之外,你应该在你的 IDE 中放置一个断点

    transporterCrudPageViewModel.InitializeTransporterForm(args.Parameter as Transporter);
    

    确保NavigationEventArgs 对象的属性Parameter 不为空。

    【讨论】:

    • 所以,问题不在于参数,参数不为空,而是在调用设置函数时await SetUpForm(enumerable)我收到此消息异常“对象引用未设置为对象的实例。”
    • @ArghArgh 关于这个实现有一些我不明白的地方,我认为它们与null 参数有关,这就是我的观点。看一下TransporterListViewModel 类的SelectedItem 属性的值。此值作为事件处理程序的 args 对象的参数传递。
    • 我已经插入了几行代码,以显示对象 Transporter Transporter tmp = new Transporter(); tmp = args.Parameter as Transporter; if (tmp != null) Debug.WriteLine(tmp.trName); 的一些属性并且输出显示值之前的异常(对象的值是正确的)Taht 是输出“在 CrudSampleMVVM.exe 未设置为对象实例的对象引用中发生了 'System.NullReferenceException' 类型的第一次机会异常。marco”
    • 问题是我之前尝试获取 Parameter 的值,它已被初始化。我不知道为什么之前调用了 Setup..
    • 好的,我试着简化我的问题。根据 Anders Gustaffson 的解决方案,我不知道在哪里/如何初始化 TrasporterCrudViewModel 中的参数值。
    猜你喜欢
    • 2019-12-11
    • 2015-12-06
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 2013-12-30
    相关资源
    最近更新 更多