Xaml Xamarin表单动态加载页面中的内容

Xaml Xamarin表单动态加载页面中的内容,xaml,xamarin,mvvm-light,xamarin.forms,Xaml,Xamarin,Mvvm Light,Xamarin.forms,我当前的设置: Xamarin表单,由iOS、Android、WP应用程序和共享PCL组成。 使用MVVM Light可以很好地分离关注点 简要介绍我想要实现的目标。我想有一个基本页,有一个取消和下一步按钮。按下“下一步”按钮时,内容将在该基本页中动态加载 Xaml视图: <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"

我当前的设置:

Xamarin表单,由iOS、Android、WP应用程序和共享PCL组成。 使用MVVM Light可以很好地分离关注点

简要介绍我想要实现的目标。我想有一个基本页,有一个取消和下一步按钮。按下“下一步”按钮时,内容将在该基本页中动态加载

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"
             x:Class="LogInPresenterView">
  <ContentPage.ToolbarItems>
    <ToolbarItem Text="Cancel" Priority="0" Order="Primary" Command="{Binding Cancel}"></ToolbarItem>
    <ToolbarItem Text="Next" Priority="1" Order="Primary" Command="{Binding Next}"></ToolbarItem>
  </ContentPage.ToolbarItems>
</ContentPage>
public class LogInPresenterViewModel : ViewModelBase
    {

        public LogInPresenterViewModel() {}

        private RelayCommand _next;
        public RelayCommand Next
        {
            get
            {
                return _next ?? (_next = new RelayCommand(async () => await DoNext()));
            }
        }

        private async Task DoNext()
        {
           // IN HERE I WOULD LIKE TO DYNCAMICALLY LOAD CONTENT / VIEWS
        }

    }
通常在元素之前会有一个StackLayout等。但是,单击下一个工具栏项时,我希望动态加载内容(具有viewmodel)

因此,我的下一步按钮的ICommand可能会检查当前的内容类型,根据这一点,我会加载另一部分内容

场景是,基本页面将与第一位内容一起加载-输入电子邮件和密码。用户输入,然后单击next(下一步),如果一切正常,内容将替换为输入安全代码的选项,保持底部关闭,顶部的next(下一步)按钮


希望这是有道理的。我知道我想在脑子里做什么,我只是不知道如何把它翻译成Xamarin的形式…

所以如果这是我。我将创建一个区域服务,contentview在其中注册一个唯一的区域名称

然后,内容将被标记为使用该区域,并且可以使用自定义演示器在适当的区域中显示视图模型的内容

我现在在旅行时打电话,但如果有帮助,我可以稍后发布一些代码:)

特里斯坦

好的

所以,第一项工作是在PCL中创建区域服务。这将看起来像这样:

using System;
using System.Collections.Generic;

namespace xxx
{
    public class RegionService : IRegionService
    {
        private Dictionary<string, object> _regionDictionary;

        public RegionService ()
        {
            _regionDictionary = new Dictionary<string, object> ();
        }

        #region IRegionService implementation

        public bool RegisterRegion (string regionName, object regionObject)
        {
            object region = null;

            _regionDictionary.TryGetValue (regionName, out region);
            if (region != null)
                _regionDictionary [regionName] = regionObject;
            else
                _regionDictionary.Add (regionName, regionObject);
            return true;
        }

        public object ResolveRegion (string regionName)
        {
            object region = null;

            _regionDictionary.TryGetValue (regionName, out region);

            if (region == null)
                throw new RegionServiceException ("Unable to resolve region with given name");

            return region;
        }

        #endregion
    }
}
然后在视图的代码隐藏中实现此接口以返回要显示的区域的名称

您现在需要一个自定义演示者来使用此区域代码。我使用MVVMCross,因此您所使用的MVVM实现的细节会有所不同,但本质上您需要这样的东西:

public async static Task PresentPage(Page page)
{

    if (typeof(IRegionView).GetTypeInfo().IsAssignableFrom(page.GetType().GetTypeInfo()))
    {

        IRegionService regionService = Mvx.Resolve<IRegionService>();
        string regionName = (page as IRegionView).GetRegionName();
        Page region = regionService.ResolveRegion(regionName) as Page;

        if (typeof(IModalPage).GetTypeInfo().IsAssignableFrom(page.GetType().GetTypeInfo()))
            await region.Navigation.PushModalAsync(page);

        else if (typeof(IPopupPage).GetTypeInfo().IsAssignableFrom(page.GetType().GetTypeInfo()))
            region.PushOverlayPage(page);

        else if (typeof(NavigationPage).GetTypeInfo().IsAssignableFrom(region.GetType().GetTypeInfo()))
            await (region as NavigationPage).PushAsync(page);

    }
}
公共异步静态任务呈现页面(第页)
{
if(typeof(IRegionView).GetTypeInfo().IsAssignableFrom(page.GetType().GetTypeInfo()))
{
IRegionService regionService=Mvx.Resolve();
字符串regionName=(页面名称为IRegionView).GetRegionName();
Page region=regionService.ResolveRegion(regionName)作为页面;
if(typeof(IModalPage).GetTypeInfo().IsAssignableFrom(page.GetType().GetTypeInfo()))
wait region.Navigation.PushModalAsync(第页);
else if(typeof(ipopulage).GetTypeInfo().IsAssignableFrom(page.GetType().GetTypeInfo()))
区域。推覆页面(第页);
else if(typeof(NavigationPage).GetTypeInfo().IsAssignableFrom(region.GetType().GetTypeInfo()))
wait(区域为NavigationPage).PushAsync(页面);
}
}

我希望这对您有用:)

您可以使用XAML动态加载Xamarin表单UI

旧答案: 这可以通过使用LoadFromXaml方法实现。它的工作原理与Silverlight/WPF中的XamlReader.Load相同。它是一个隐藏的方法,只能通过反射来访问。这里有一篇关于如何做到这一点的文章:

但是,我想请您转到Xamarin的此功能请求,并要求将该方法公开,使其成为完全受支持的功能:

如果您能提供一些代码,那就太好了。。。我现在有点困了,希望你能帮我。我已经创建了一个LogInPresenterView。。。看来我开始的方向是对的。嗨,特里斯坦,谢谢你。我不确定这是否是我想要的,但我回家后会更详细地看一看。我可能没有正确描述这个问题。感谢您提供代码等。
using System;

namespace xxx
{
    public interface IRegionView
    {
        string GetRegionName ();
    }
}
public async static Task PresentPage(Page page)
{

    if (typeof(IRegionView).GetTypeInfo().IsAssignableFrom(page.GetType().GetTypeInfo()))
    {

        IRegionService regionService = Mvx.Resolve<IRegionService>();
        string regionName = (page as IRegionView).GetRegionName();
        Page region = regionService.ResolveRegion(regionName) as Page;

        if (typeof(IModalPage).GetTypeInfo().IsAssignableFrom(page.GetType().GetTypeInfo()))
            await region.Navigation.PushModalAsync(page);

        else if (typeof(IPopupPage).GetTypeInfo().IsAssignableFrom(page.GetType().GetTypeInfo()))
            region.PushOverlayPage(page);

        else if (typeof(NavigationPage).GetTypeInfo().IsAssignableFrom(region.GetType().GetTypeInfo()))
            await (region as NavigationPage).PushAsync(page);

    }
}