首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Xamarin forms 4带有复杂参数的shell导航

Xamarin forms 4带有复杂参数的shell导航
EN

Stack Overflow用户
提问于 2019-08-19 17:54:59
回答 4查看 4.9K关注 0票数 3

我正在将一个带有棱镜的xamarin forms 3.x应用程序迁移到带有shell导航的Forms4。

我是否必须创建我的自定义解决方案来将复杂的参数传递给新页面,或者Xamarin有一些内置的功能来接收字符串参数以外的其他参数?

谢谢。

EN

回答 4

Stack Overflow用户

发布于 2019-08-19 19:10:14

据我所知,在阅读文档时,唯一的示例是传递简单的数据,比如在导航时传递字符串。

然而,对于下一个版本(我假设这就是您所指的情况),我能够找到一个问题(和拉取请求),用于传递对象/模型。

你可以在here上追踪它。

票数 5
EN

Stack Overflow用户

发布于 2019-11-18 03:27:02

您总是可以将模型序列化为JSON字符串,然后在另一端将其反序列化?

代码语言:javascript
运行
复制
    async void Handle_ItemTapped(object sender, ItemTappedEventArgs e)
    {
        if (e.Item == null)
            return;

        DailyPnL PnLClicked = (DailyPnL)e.Item;
        string jason = await Task.Run(() => JsonConvert.SerializeObject(PnLClicked));

        await Shell.Current.GoToAsync($"viewdailypnl?pnlmodel={jason}");

        //Deselect Item
        ((ListView)sender).SelectedItem = null;
    }

然后在后面的代码中:

代码语言:javascript
运行
复制
    public string pnlmodel
    {
        set
        {
            string derulo = Uri.UnescapeDataString(value);
            viewModel.PnL =  Task.Run(() => JsonConvert.DeserializeObject<DailyPnL>(derulo)).Result;

        }
    }
票数 4
EN

Stack Overflow用户

发布于 2020-05-18 23:53:49

我已经运行了一些测试,它们似乎正在工作。我对Xamarin比较陌生,因此建议谨慎,并欢迎对我可能忽略的任何潜在问题的任何反馈。

我编写了一个外壳扩展来接受数据对象参数'navigationData‘,如下所示:

代码语言:javascript
运行
复制
await Shell.Current.GoToAsync(state, navigationData, animate);

代码语言:javascript
运行
复制
namespace Xamarin.Forms
{
    public static class ShellExtensions
    {
        public static async Task GoToAsync(this Shell shell, ShellNavigationState state, object navigationData, bool animate=false)
        {
            shell.Navigated += async (sender, e) =>
            {
                if ((Shell.Current?.CurrentItem?.CurrentItem as IShellSectionController)?.PresentedPage is MyContentPage
                    p) await p.InitializeAsync(navigationData).ConfigureAwait(false);
            };
            await shell.GoToAsync(state, animate);
        }
    }
}

如上所示,扩展名:-

  1. 挂钩到外壳程序的“Navigated”事件,
  2. 以“MyContentPage”的形式检索“当前视图(页面)”,即子类ContentPage,
  3. 在视图上调用InitializeAsync方法,传入navigationData参数
  4. 视图,然后在绑定上下文(视图模型)上调用InitializeAsync方法,将navigationData参数传递到viewModel。

在上面的扩展方法中,'MyContentPage‘是ContentPage的一个自定义抽象子类,它有一个InitializeAsync(navigationData)方法,它只是在viewModel (视图的绑定上下文)上调用一个类似的方法。类似地,ViewModels子类化了一个具有虚拟InitializeAsync(navigationData)自定义ViewModelBase类。这可以在viewModel中用所需的导航数据实现和处理来覆盖。

视图、ViewModels和相关基类的简化示例如下所示

代码语言:javascript
运行
复制
using System.Threading.Tasks;
using MyXamarinApp.ViewModels;
using Xamarin.Forms;

namespace MyXamarinApp.Views
{
    public ItemDetailPage : MyContent<ItemDetailViewModel>{}

    public ItemPage : MyContentPage<ItemViewModel>{}

    public abstract class MyContentPage<T> : MyContentPage where T : ViewModelBase
    {
        protected T Vm;

        protected override ViewModelBase VmBase => Vm as ViewModelBase;

        protected MyContentPage()
        {
            BindingContext = Vm = ViewModelLocator.Resolve<T>();
        }

        private Comand _showDetailCommand;
        public Command ShowDetailCommand
        {
            get { return _showDetailCommand ??= new Command(async () => 
                await Shell.Current.GoToAsync("itemDetail", new NavigationDataObject())); }
        }
    }


    public abstract class MyContentPage : ContentPage
    {
        protected abstract ViewModelBase VmBase { get; }

        public virtual async Task InitializeAsync(object navigationData)
        {
            await VmBase.InitializeAsync(navigationData);
        }
    }
}

public class NavigationDataObject
{
    'Properties' etc.
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

namespace MyXamarinApp.ViewModels
{
    public ItemViewModel : ViewModelBase{}

    public ItemDetailViewModel : ViewModelBase
    {
        private NavigationDataObject _navData;
        public override async Task InitializeAsync(object navigationData)
        {
            if (navigationData is NavigationDataObject navData)
            {
                _navData = navData;
            }
            await base.InitializeAsync(navigationData);
        }
    }

    public abstract class ViewModelBase
    {

        public virtual Task InitializeAsync(object navigationData)
        {
            return Task.FromResult(false);
        }
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57554375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档