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

时间:2015-02-21 22:23:24

标签: xaml xamarin mvvm-light xamarin.forms

我目前的设置:

Xamarin Forms,包含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>

ViewModel代码:

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等。但是,在单击下一个工具栏项时,我想动态加载内容(具有视图模型)。

因此,我的下一个按钮的ICommand可能会检查当前内容类型是什么,并根据我的内容加载其他内容。

方案是,基页将加载第一部分内容 - 输入电子邮件和密码。用户输入然后单击下一步,如果一切正常,则内容将替换为输入安全代码的选项,将基本关闭和下一步按钮保持在顶部。

希望这是有道理的。我知道自己想要做什么,我只是不知道如何将其翻译成Xamarin表格......

3 个答案:

答案 0 :(得分:1)

好的,

因此,首要任务是在您的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
    }
}

当您使用动态内容创建页面时,在您的代码中注册动态内容视图:

ContentView contentView = this.FindById<ContentView>("myContentView");
regionService.RegisterRegion("DynamicView", contentView);

您需要为视图和网页创建一个界面,以指示他们希望在哪个区域展示:

using System;

namespace xxx
{
    public interface IRegionView
    {
        string GetRegionName ();
    }
}

然后在您的视图后面为您的视图实现此接口,以返回要显示的区域的名称。

您现在需要一个自定义演示者才能使用此区域代码。我使用的是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);

    }
}

我希望这对你有用:)

答案 1 :(得分:0)

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

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

我现在正在旅行时使用手机,但如果有帮助,我可以稍后发布一些代码:)

特里斯坦

答案 2 :(得分:0)

您可以使用XAML动态加载Xamarin Forms UI。

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

但是,我想请求您在Xamarin上查看此功能请求,并要求将该方法公之于众,以使其成为完全受支持的功能: https://forums.xamarin.com/discussion/comment/252626