如何在mvvmlight中实现自定义导航服务 [英] How to implement custom navigation service in mvvmlight

查看:97
本文介绍了如何在mvvmlight中实现自定义导航服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对现有的MVVMlight导航界面方法不太满意,而且这非常少,我想实现自己的导航界面,在其中可以公开操作导航堆栈并将其与MVVM light集成的复杂方法.

I am not quite comfortable with the existing MVVMlight navigation interface methods and that is very minimal and I want to implement my very own navigational interface in which I can expose sophisticated methods that manipulates the navigational stack and integrate it with the MVVM light.

非常感谢您提供实现此目标的任何指导

Any guidance on achieving this is very much appreciated

更新:

我想为页面之间的移动实现其他过渡,例如页面卷曲,翻转,旋转等

I would like to implement other transitions for movement between pages like page curl,flip,rotate etc

推荐答案

下面是一个完整的实现示例,该示例将通过添加一个新接口完全替代MvvmLight中的接口来解决该问题,并允许您选择是使用动画还是使用动画.不是.在此示例中,我们添加了控制导航是否应设置动画的功能:

Here's a full implementation example that would solve the problem by adding a new interface that fully replaces the one from MvvmLight and also allows you to choose whether to use animations or not. In this example, we add the ability to control whether the navigation should be animated or not:

界面

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的位置使用.

From here, you can add other methods you would like. Make sure to inject this or use it directly where you were using your MvvmLight one before.

这篇关于如何在mvvmlight中实现自定义导航服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆