Сообщения об ошибках MahApps с использованием MVVM

Простой вопрос для Магэпп Веселых людей. Я внедрил приложение, использующее ваши великолепные средства управления с помощью metro, используя Caliburn.Micro для материалов MVVM. Новые диалоговые окна сообщений выглядят великолепно, но в настоящее время нет четкого способа запуска этих диалогов без написания моей собственной обертки (которой я не против). Однако, было ли это сделано или есть что-то, что я пропустил, чтобы я мог вызывать окно сообщения из модели представления без каких-либо проблем?

Спасибо за ваше время.

Ответы

Ответ 1

Я создал оболочку для вызова диалогового окна сообщения MahApps.Metro, потому что у меня была такая же проблема с моим MVVM-проектом. Мне пришлось создать список открытых окон, в котором первое окно всегда будет моим MainWindow.

Здесь мой код DialogService:

public async Task<MessageDialogResult> ShowMessage(string message, MessageDialogStyle dialogStyle)
{
    var metroWindow = (_openedViews.First() as MetroWindow);
    metroWindow.MetroDialogOptions.ColorScheme = MetroDialogColorScheme.Accented;

    return await metroWindow.ShowMessageAsync("MY TITLE", message, dialogStyle, metroWindow.MetroDialogOptions);
}

Этот код можно использовать для отображения диалогов с результатом или без него. Вы можете заметить, что его возвращение - это Task<MessageDialogResult>, поэтому, если вы хотите получить результат, вы можете сделать это на вашем ViewModel:

MessageDialogResult result = await _dialog.ShowMessage("SOME MESSAGE HERE", MessageDialogStyle.AffirmativeAndNegative).ConfigureAwait(false);

if (result == MessageDialogResult.Affirmative)
{
    //Do something
}

Кстати, если метод, вызывающий ShowMessage(), нуждается в результате, вы ДОЛЖНЫ поместить async в присваивание, иначе это не сработает. (если вы хотите показать диалог сообщений, это не обязательно).

Мой проект использует Framework 4.0, и я могу использовать только async/await из-за пакета, который мне пришлось установить из NuGet. Вы можете получить ссылку для документации MSDN этого пакета, и вы можете скачать пакет здесь.

Я надеюсь, что он решил вашу проблему.

EDIT:

Я реализовал метод на моем DialogService, чтобы открыть любые окна из любого ViewModel. Этот метод использует Microsoft Unity framework для создания экземпляра моего объекта, а затем я вызываю Show(), чтобы открыть себя. Перед вызовом Show() я добавляю это окно в список.

Смотрите мой код:

public void ShowView<T>(params ParameterOverride[] parameter)
{
    var window = UnityServiceConfigurator.Instance.Container.Resolve<T>(parameter) as MetroWindow;

    if (window != null)
    {
        if (Application.Current.MainWindow != window)
        {
            window.Owner = Application.Current.MainWindow;
            var ownerMetroWindow = (window.Owner as MetroWindow);

            if (!ownerMetroWindow.IsOverlayVisible())
                ownerMetroWindow.ShowOverlayAsync();
        }

        if (!_openedViews.Contains(window))
            _openedViews.Add(window);

        window.Show();
    }
}

Вот как я вызываю из моей модели ViewModel:

_dialog.ShowView<MyView>();

Если на вашем полном программном обеспечении имеется только одно окно, вы можете сохранить его ссылку и использовать его, чтобы показать ShowMessageAsync(), не создавая список только для использования Первого. Вот так:

var metroWindow = (Application.Current.MainWindow as MetroWindow);

Ответ 2

Начиная с 1.1.3-ALPHA * (чтобы стать 1.2.0) MahApps предоставляет помощник для запуска диалогов с виртуальной машины, которая работает в нескольких установках Windows:

1) Используйте прикрепленное свойство в своем окне, чтобы зарегистрировать вашу модель просмотра с помощью подсистемы диалога.

Предполагая, что ваши представления DataContext настроен на модель представления, откуда вы хотите запустить диалог, добавьте следующие атрибуты:

<Controls:MetroWindow 
    xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
    Dialog:DialogParticipation.Register="{Binding}">

2) Захват/ввод DialogCoordinator:

new MainWindowViewModel(DialogCoordinator.Instance);

3) Покажите свое диалоговое окно из модели просмотра. Используйте "this" в качестве контекста, чтобы MahApps мог жениться на вашей модели представления в правильном окне:

_dialogCoordinator.ShowMessageAsync(this, "Message from VM", "MVVM based dialogs!")

Ответ 3

Если у вас есть только один экземпляр вашего окна, вы можете попробовать что-то вроде этого:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Caliburn.Micro;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;

namespace Busyboy
{
    [Export(typeof(IShell))]
    class MainViewModel : PropertyChangedBase, IShell
    {
        public void StartPomodoro()
        {
            var mainview0 = System.Windows.Application.Current.Windows.OfType<MainView>().FirstOrDefault();
            mainview0.ShowInputAsync("New Pomodoro", "Enter a name for new pomodoro session.");
        }
    }
}

И у вас должен быть способ идентификации каждого окна, чтобы вы могли отфильтровывать окна. Обратите внимание на импорт "Metro.Controls.Dialogs", который содержит расширения.