mvvm light - NavigationService / DialogService classes not found
Asked Answered
C

2

10

Should be a simple answer, but I'm not seeing it.

MVVM Light v5 introduced a NavigationService and DialogService. I wanted to make a sample application to play around with them. The advice seems to be that all i need do is register them in the ViewModelLocator as such:

SimpleIoc.Default.Register<IDialogService, DialogService>();

The IDialogService needs the Galasoft.MvvmLight.Views namespace, which gets automatically resolved, but the DialogService class cannot be found, and VS cannot recommend a namespace to import.

Similar for NavigationService

Careerist answered 19/5, 2015 at 6:3 Comment(0)
E
5

I'm assuming you are using WPF, in which case there isn't a default implementation of IDialogService and INavigationService. Thus you will need to create your own implementations.

Edmondson answered 19/5, 2015 at 7:5 Comment(2)
That surprises me, I would've thought that WPF would be the first to have a default implementation. Do you know of anywhere that has a code sample for a basic service for both of these (so I can see the functionality it will need to implement)Careerist
Answered my own comment. This article gives me enough to work with.Careerist
V
5

Here is the code based on some of his sample applications... thanks Laurent u rock! it took me a while to find this... hope this helps :)

DialogService Implementation

/// <summary>
/// Example from Laurent Bugnions Flowers.Forms mvvm Examples
/// </summary>
public class DialogService : IDialogService
{
    private Page _dialogPage;

    public void Initialize(Page dialogPage)
    {
        _dialogPage = dialogPage;
    }

    public async Task ShowError(string message,
        string title,
        string buttonText,
        Action afterHideCallback)
    {
        await _dialogPage.DisplayAlert(
            title,
            message,
            buttonText);

        if (afterHideCallback != null)
        {
            afterHideCallback();
        }
    }

    public async Task ShowError(
        Exception error,
        string title,
        string buttonText,
        Action afterHideCallback)
    {
        await _dialogPage.DisplayAlert(
            title,
            error.Message,
            buttonText);

        if (afterHideCallback != null)
        {
            afterHideCallback();
        }
    }

    public async Task ShowMessage(
        string message,
        string title)
    {
        await _dialogPage.DisplayAlert(
            title,
            message,
            "OK");
    }

    public async Task ShowMessage(
        string message,
        string title,
        string buttonText,
        Action afterHideCallback)
    {
        await _dialogPage.DisplayAlert(
            title,
            message,
            buttonText);

        if (afterHideCallback != null)
        {
            afterHideCallback();
        }
    }

    public async Task<bool> ShowMessage(
        string message,
        string title,
        string buttonConfirmText,
        string buttonCancelText,
        Action<bool> afterHideCallback)
    {
        var result = await _dialogPage.DisplayAlert(
            title,
            message,
            buttonConfirmText,
            buttonCancelText);

        if (afterHideCallback != null)
        {
            afterHideCallback(result);
        }

        return result;
    }

    public async Task ShowMessageBox(
        string message,
        string title)
    {
        await _dialogPage.DisplayAlert(
            title,
            message,
            "OK");
    }
}

NavigationService Implementation

/// <summary>
/// Example from Laurent Bugnions Flowers.Forms mvvm Examples
/// </summary>
public class NavigationService : INavigationService
{
    private readonly Dictionary<string, Type> _pagesByKey = new Dictionary<string, Type>();
    private NavigationPage _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()
    {
        _navigation.PopAsync();
    }

    public void NavigateTo(string pageKey)
    {
        NavigateTo(pageKey, null);
    }

    public void NavigateTo(string pageKey, object parameter)
    {
        lock (_pagesByKey)
        {
            if (_pagesByKey.ContainsKey(pageKey))
            {
                var type = _pagesByKey[pageKey];
                ConstructorInfo constructor = null;
                object[] parameters = null;

                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);
            }
            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;
    }
}
Vocalist answered 3/8, 2016 at 22:22 Comment(2)
@Ergli, First, thanks for providing the code for everyone. I discovered that the DialogService and NavigationService code is apparently only for Xamarin. Xamarin conflicts with the "regular" Windows via the Page's DisplayAlert() in the DialogService. The NavigationService conflicts involve the NavigationPage object. I will have to find a workaround or a "regular" version.Unhook
For "regular" Windows and my needs to customize the modal dialog, I eventually went with a open source MVVM Dialogs package found at github.com/FantasticFiasco/mvvm-dialogs . The MVVM Light example is located at: github.com/FantasticFiasco/…Unhook

© 2022 - 2024 — McMap. All rights reserved.