我对现有的MVVMlight导航界面方法并不太满意,因为它非常简单,所以我想实现自己的导航界面,可以公开操纵导航堆栈的复杂方法,并将其与MVVM Light集成。
如果有关于如何实现这一点的指导,将不胜感激。
更新:
我希望实现其他页面之间的转场效果,例如翻页、翻转、旋转等。
如果有关于如何实现这一点的指导,将不胜感激。
更新:
我希望实现其他页面之间的转场效果,例如翻页、翻转、旋转等。
public interface ICustomNavigationService
{
string CurrentPageKey { get; }
void GoBack(bool animate = true);
void NavigateTo(string pageKey, bool animate = true);
void NavigateTo(string pageKey, object parameter, bool animate = true);
}
实施
public class NavigationService : ICustomNavigationService
{
private readonly Dictionary<string, Type> _pagesByKey = new Dictionary<string, Type>();
private NavigationPage _navigation;
public NavigationPage Navigation
{
get
{
return _navigation;
}
}
public string CurrentPageKey
{
get
{
lock (_pagesByKey)
{
if (_navigation.CurrentPage == null)
{
return null;
}
var pageType = _navigation.CurrentPage.GetType();
return _pagesByKey.ContainsValue(pageType)
? _pagesByKey.First(p => p.Value == pageType).Key
: null;
}
}
}
public void GoBack(bool animate = true)
{
_navigation.PopAsync(animate);
MessagingCenter.Send<INavigationService>(this, "NAVIGATING");
}
public void NavigateTo(string pageKey, bool animate = true)
{
NavigateTo(pageKey, null, animate);
MessagingCenter.Send<INavigationService>(this, "NAVIGATING");
}
public void NavigateTo(string pageKey, object parameter, bool animate = true)
{
lock (_pagesByKey)
{
if (_pagesByKey.ContainsKey(pageKey))
{
var type = _pagesByKey[pageKey];
ConstructorInfo constructor;
object[] parameters;
if (parameter == null)
{
constructor = type.GetTypeInfo()
.DeclaredConstructors
.FirstOrDefault(c => !c.GetParameters().Any());
parameters = new object[]
{
};
}
else
{
constructor = type.GetTypeInfo()
.DeclaredConstructors
.FirstOrDefault(
c =>
{
var p = c.GetParameters();
return p.Count() == 1
&& p[0].ParameterType == parameter.GetType();
});
parameters = new[]
{
parameter
};
}
if (constructor == null)
{
throw new InvalidOperationException(
"No suitable constructor found for page " + pageKey);
}
var page = constructor.Invoke(parameters) as Page;
_navigation.PushAsync(page, animate);
}
else
{
throw new ArgumentException(
string.Format(
"No such page: {0}. Did you forget to call NavigationService.Configure?",
pageKey),
"pageKey");
}
}
}
public void Configure(string pageKey, Type pageType)
{
lock (_pagesByKey)
{
if (_pagesByKey.ContainsKey(pageKey))
{
_pagesByKey[pageKey] = pageType;
}
else
{
_pagesByKey.Add(pageKey, pageType);
}
}
}
public void Initialize(NavigationPage navigation)
{
_navigation = navigation;
}
}
从这里开始,您可以添加其他方法。确保注入此方法或直接在您之前使用的 MvvmLight 中使用它。
NavigationRenderer
中自定义实现。这个例子的重点是展示如何创建一个自定义接口的自定义实现,并将其用于 MvvmLight 的 NavigationService。如果您想要特殊的动画效果,您需要自己编写或从其他问题中提出分离的问题。 - SuavePirate
将它与MVVM light集成
?你可以创建自己的ICustomNavigationService
接口,为不同的操作系统实现它,然后在SimpleIoc
容器中注册实现。如果你对不同平台上的导航方式不太熟悉,可以在这里查看源代码 https://mvvmlight.codeplex.com/SourceControl/latest ,看看MVVM light
的作者是如何实现的。 - Florian MoserISharathNavigationService
,并定义所有必要的操作。你可以在共享代码中使用这个接口。然后,在每个平台上实现它(例如WindowsNavigationService
),并使用SimpleIoc
容器将其注册到接口中(例如SimpleIoc.Default.Register<ISharathNavigationService, WindowsNavigationService>()
)。最后,在共享代码中,你可以调用SimpleIoc
容器来获取ISharathNavigationService
的实例(类似于SimpleIoc.Default.GetInstance<ISharathNavigationService>()
)。 - Florian Moser