【问题标题】:Pass data parameter from model to next page Prism Xamarin Forms将数据参数从模型传递到下一页 Prism Xamarin Forms
【发布时间】:2019-04-30 10:17:53
【问题描述】:

我需要使用 Prism 将数据从 ViewModel 1 传递到 ViewModel 2。

TodoItem 是我的模型,带有字符串:

public TodoItem _todotItem { get; set; }

private readonly INavigationService _navigationService;

我在构造函数中赋值了:

public MainPageViewModel(INavigationService navigationService, TodoItem todotItem)
{
    _navigationService = navigationService;
    _todotItem = todotItem;
}

这是我用来导航到下一页的代码(包括参数):

NavigationParameters navParams = new NavigationParameters();
navParams.Add("PassedValue", _todoItem.name);

_navigationService.NavigateAsync("SecondPage", navParams);

当我在 _todoItem.name 上设置断点时,它显示 null。在我单击listview 之前获取数据。我错过了什么?

编辑:

这就是我的导航方式(点击来自listview):

private EventItem _selectedEvent { get; set; }
public EventItem SelectedEvent
{
    get { return _selectedEvent; }  
    set
    {
        if (_selectedEvent != value)
        {
            if (Device.RuntimePlatform == Device.iOS)
            {
                _selectedEvent = null;
            }
            else
            {
                _selectedEvent = value;
            }
            NavigationParameters navParams = new NavigationParameters();

            navParams.Add("PassedValue", _todoItem.name);


            _navigationService.NavigateAsync("SecondPage", navParams);
        }
    }
}

我确实使用正确的方法来捕获第二个 ViewModel 上的参数(但是,我在第一个 ViewModel 中得到 null):

public void OnNavigatingTo(INavigationParameters parameters)
{
    if (parameters.ContainsKey("PassedValue"))
    {
        _todo = (string)parameters["PassedValue"];

        OnPropertyChanged("Todo");
    }

}

我使用HTTPClient 来获取数据。

【问题讨论】:

  • 如果您安装了 ReSharper,它会告诉您 _todoItem 的命名约定不正确。
  • @samis 你的意思是大写?我改变了它,但仍然为空。
  • 您可以改用var navParams = new NavigationParameters();
  • TodoItem 成员property,所以public TodoItem TodotItem { get; set; }EventItemfield,所以private EventItem _selectedEvent
  • @samis 更改后仍然为空:var navParams = new NavigationParameters();

标签: c# xamarin xamarin.forms prism


【解决方案1】:

为了捕获第二页上的参数,您必须使用Prism.Navigation.INavigationAware。请检查下面的代码,也许会对您有所帮助。

./Views/ItemView.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms" 
    prism:ViewModelLocator.AutowireViewModel="True" 
    x:Class="Project.Views.ItemView"
    Title="{Binding Title}">

    <StackLayout>
        <!-- List View -->
        <ListView ItemsSource="{Binding Items}" 
                  CachingStrategy="RecycleElement" 
                  HorizontalOptions="FillAndExpand"
                  VerticalOptions="FillAndExpand" 
                  HasUnevenRows="True" 
                  SelectionMode="None">
            <ListView.Behaviors>
                <b:EventToCommandBehavior EventName="ItemTapped" 
                                          Command="{Binding ItemTappedCommand}" 
                                          EventArgsParameterPath="Item" />
            </ListView.Behaviors>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <!-- Data Template Cell -->
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>

</ContentPage>

./ViewModels/ViewModelBase.cs

using Prism;
using Prism.Mvvm;
using Prism.Navigation;
using System;

namespace Project.ViewModels
{
    // INavigationAware provides a way for objects involved in navigation to be notified of navigation activities.
    public class ViewModelBase : BindableBase, INavigationAware, IDestructible
    {
        // ...

        protected INavigationService NavigationService { get; private set; }

        public ViewModelBase(INavigationService navigationService) => NavigationService = navigationService;

        /// <summary>
        /// Called when the implementer is being navigated away from.
        /// </summary>
        public virtual void OnNavigatedFrom(INavigationParameters parameters)
        {

        }

        /// <summary>
        /// Called when the implementer has been navigated to.
        /// </summary>
        public virtual void OnNavigatedTo(INavigationParameters parameters)
        {

        }

        // ...
    }
}

./ViewModels/ItemViewModel.cs

using Prism.Navigation;
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;

namespace Project.ViewModels
{
    public class ItemViewModel : ViewModelBase
    {
        // ...

        private ObservableCollection<ItemList> _items;
        public ObservableCollection<ItemList> Items
        {
            get => _items;
            set => SetProperty(ref _items, value);
        }

        public ICommand ItemTappedCommand => new AsyncCommand(ItemTappedCommandAsync);

        public ItemViewModel(INavigationService navigationService)
            : base(navigationService)
        {
            Items = new ObservableCollection<ItemList>();
            // Load the data
        }

        // ...

        private async Task ItemTappedCommandAsync(object item)
        {
            var navParams = new NavigationParameters
            {
                { "ItemSelected", (Item)item }
            };

            await NavigationService.NavigateAsync(nameof(ItemDetailView), navParams);
        }
    }
}

./ViewModels/ItemDetailViewModel.cs

using Prism.Navigation;
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;

namespace Project.ViewModels
{
    public class ItemDetailViewModel : ViewModelBase
    {
        // ...

        public override void OnNavigatingTo(INavigationParameters parameters)
        {
            // Capture the parameter
            System.Diagnostics.Debug.WriteLine(parameters);
        }

        // ...
    }
}

【讨论】:

  • 我也需要 ViewModelBase 中的 PropertyChanged,但它说我隐藏了一些东西。我应该担心吗?也许我不需要PropertChanged。谢谢您的帮助。 @贾德奥利维拉
  • 如何在新页面中使用 xaml 中的字符串捕获参数? @贾德
  • PropertyChanged 已经通过Prism.Mvvm.BindableBase 实现,然后您可以在您的属性中使用。例如:set =&gt; SetProperty(ref _isBusy, value);@KalleP
  • NavigationParameters 是一个 KeyValuePair,所以你只需要使用键 'ItemSelected' 来选择值对象 'Item' > var itemSelected = (Item)parameters["ItemSelected"];
  • 非常感谢。只是希望我可以更改 itemssource 以转到 viewmodel 而不是后面的代码。使用 viewmodel 时显示数据时遇到问题。 @Jader Oliveria
猜你喜欢
  • 2017-05-28
  • 2017-01-24
  • 1970-01-01
  • 2020-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-30
相关资源
最近更新 更多