我目前的设置:
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表格......
答案 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