MVVMCross Как реализовать ContentDialog - PullRequest
0 голосов
/ 01 сентября 2018

У меня есть небольшой пример github repo , в котором мне нравится открывать пользовательский ContentDialog (SpeechDialog) после нажатия кнопки, используя MVVMCross framework .

Если я реализую ContentDialog с MVVM без каркаса , MainView будет выглядеть так:

public sealed partial class MainView : Page
{
    public MainView()
    {
        this.InitializeComponent();
        ISpeechDialogService dialog = new SpeechDialogService();
        MainViewModel= new MainViewModel(dialog);
    }
    public MainViewModel MainViewModel{ get; set; }
}

Но в MVVMCross У меня есть атрибутированный MainView, и я не знаю, как передать ContentDialog:

[MvxViewFor(typeof(MainViewModel))]
public sealed partial class MainView : MvxWindowsPage
{
    public MainView()
    {
        InitializeComponent();
    }
}

Некоторый код для лучшего понимания:

SpeechDialogService.cs:

public class SpeechDialogService : ISpeechDialogService
{
    public async Task ShowAsync()
    {
        var contentDialog = new Speech();
        await contentDialog.ShowAsync();
    }

}

прямая ссылка на Speech.xaml

TL; DR

Правильно ли подходит мой подход? Если да, как я могу передать ContentDialog в MainViewModel? Если нет, как реализовать ContentDialog с MVVMCross ?

1 Ответ

0 голосов
/ 03 сентября 2018

Я думаю, что вы можете использовать ViewModelLocator здесь и использовать шаблон MVVM, независимо от структуры. Смотрите пример реализации.

public class ViewModelLocator
{
    public MainPageViewModel MainPageViewModel
    {
        get
        {
            ISpeechDialogService dialogService = new SpeechDialogService();
            MainPageViewModel vm = new MainPageViewModel(dialogService);
            return vm;
        }
    }
}

Здесь вы можете использовать Autofac для разрешения зависимостей ViewModels, а также сделать сервис синглтоном https://autofaccn.readthedocs.io/en/latest/resolve/index.html

Затем в вашем App.xaml добавьте ресурс для локатора:

<Application.Resources>
    <services:ViewModelLocator x:Key="Locator" />
</Application.Resources>

Тогда на вашей странице (желательно не в коде позади) вы должны назначить свой DataContext следующим образом:

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    d:DesignHeight="450" d:DesignWidth="800"
    DataContext="{Binding MainPageViewModel, Source={StaticResource Locator}}">

</Page>

Тогда ваша ViewModel должна выглядеть так:

using App1.Services;

namespace App1.ViewModels
{
    public class MainPageViewModel
    {
        private readonly ISpeechDialogService _speechDialogService;
        public MainPageViewModel(ISpeechDialogService speechDialogService)
        {
            _speechDialogService = speechDialogService;
        }
    }
}

Ваш сервис диалога выглядит так:

using System.Threading.Tasks;

namespace App1.Services
{
    public class SpeechDialogService : ISpeechDialogService
    {
        public async Task ShowAsync()
        {
            var contentDialog = new Speech();
            await contentDialog.ShowAsync();
        }
    }
}

Надеюсь, это поможет.

...