【问题标题】:Xamarin Prism cannot navigate with parametersXamarin Prism 无法使用参数导航
【发布时间】:2018-03-12 15:07:34
【问题描述】:

对于我的应用程序,我使用框架创建自己的按钮并向其添加轻触手势。在这里,我使用 prism 的导航到带有参数的特定页面。然而。我要使用的视图模型不会触发导航到方法。这是一些代码。

在调试过程中,添加参数似乎没有问题。然而,视图模型的构造函数被调用。

按钮

public class FolderButton : Frame
{
    public FolderButton(Folder folder, INavigationService navigationService)
    {
        var navParams = new NavigationParameters();
        navParams.Add("folder", folder);
        GestureRecognizers.Add(new TapGestureRecognizer()
        {
            Command = new Command(async () => { await navigationService.NavigateAsync("FolderInventory", navParams); }),
        });

        BackgroundColor = Color.CornflowerBlue;
        var thickness = new Thickness();
        thickness.Bottom = 10;
        thickness.Left = 10;
        thickness.Right = 10;
        thickness.Top = 10;
        Margin = thickness;
        CornerRadius = 5;

        var completeStack = new StackLayout();
        var imgStack = new StackLayout();
        imgStack.Padding = thickness;
        imgStack.Children.Add(new Image { Source = "folder.png" });
        completeStack.Children.Add(imgStack);
        var lblStack = new StackLayout();
        lblStack.Padding = thickness;
        lblStack.Children.Add(new Label
        {
            Text = folder.Name,
            HorizontalTextAlignment = TextAlignment.Center,
            VerticalTextAlignment = TextAlignment.Start
        });
        completeStack.Children.Add(lblStack);

        Content = completeStack;
    }
}

称为视图模型

public class FolderInventoryViewModel : BindableBase, INavigatedAware
{
    public Folder Folder => _folder;

    private readonly INavigationService _navigationService;
    private Folder _folder;
    private readonly ISQLiteService _sqlService;
    private List<Frame> _buttons;

    public List<Frame> Buttons
    {
        get => _buttons;
        set => _buttons = value;
    }

    public FolderInventoryViewModel(Folder folder, INavigationService navigationService, ISQLiteService sqlService)
    {
        _folder = folder;
        _sqlService = sqlService;
        _navigationService = navigationService;
        GetItemsForFolder();
    }

    private void GetItemsForFolder()
    {
        var itemList = _sqlService.GetAllFolderItems(Folder.Name);

        foreach (var item in itemList)
        {
            var itemButton = new ItemButton(_navigationService, item);
            _buttons.Add(itemButton);
        }
    }

    public void OnNavigatedFrom(NavigationParameters parameters)
    {
        if (parameters["folder"] is Folder folder)
        {
            _folder = folder;
        }

    }

    public void OnNavigatedTo(NavigationParameters parameters)
    {
        if (parameters["folder"] is Folder folder)
        {
            _folder = folder;
        }
    }
}

【问题讨论】:

  • 这个想法是 Prism 通过解析依赖项(INavigationService 和 ISQLiteService)并通过构造函数注入它们来实例化 ViewModel。之后,Prism 将使用您指定的参数调用 OnNavigatedTo。所以在这种情况下,我认为你可以删除构造函数的“文件夹”参数。希望这会有所帮助。

标签: xamarin xamarin.forms prism


【解决方案1】:

这不是使用框架的本质。要正确使用带有NavigationParameters 的 Prism,您首先要正确维护其背后的 MVVM 理念。

例如

<Button Command="{Binding testCommand}" text="TestButton"/>

您的 ViewModel(请原谅,您需要将 NavigationService 注入 ViewModel 的构造函数)

private DelegateCommand _testCommand;
public DelegateCommand testCommand =>
        _testCommand?? (_testCommand= new DelegateCommand(ExecuteTest));
private void ExecuteTest()
{
    NavigationParameters navigationParameters = new NavigationParameters();
    navigationParameters.Add("yourParameterId", value);
    NavigationService.NavigateAsync("YourPage", navigationParameters);
}

然后进入下一页

将 INavigationAware 继承到您的 NextPage:YourNextPage: BaseViewModel, INavigationAware

INavigationAware 有 3 个方法 NavigatingTo、NavigatedTo、NavigatedFrom

在 OnNavigatedTo 里面可以调用你传递的参数

public void OnNavigatedTo(NavigationParameters parameters)
{
    //You can check if parameters has value before passing it inside

    if(parameters.ContainsKey("YourParameterId")
    {
         yourItem = (dataType)parameters[YourParameterId];
    }
}

另请注意:构造函数总是在导航方法之前被调用

【讨论】:

  • 我试过你说的。使其更mvvm。需要更多的工作。但是 atm 我从代码中得到一个错误。公共 DelegateCommand FolderClick => _folderClick?? (_folderClick = new DelegateCommand(OnFolderClick));私有列表 _文件夹;公共无效 OnFolderClick(int count) { var navParams = new NavigationParameters(); navParams.Add("文件夹", _folders[count]); _navigationService.NavigateAsync("FolderInventory", navParams); } 这就是我现在得到的
  • @BjornFontaine 你修好了吗?抱歉回复晚了,因为是我们的应用程序推出,一直很忙。现在我不知道您要做什么,首先,错误是什么?原因可能是因为您传递给的参数。对不起,我以为你只是在正常传递参数。
猜你喜欢
  • 1970-01-01
  • 2016-06-06
  • 1970-01-01
  • 2018-11-30
  • 2018-02-09
  • 1970-01-01
  • 2013-10-24
  • 2016-11-21
  • 2021-03-25
相关资源
最近更新 更多